Ускорить скомпилированные программы, используя информацию времени выполнения, как, например, JVM делает это?

Java-программы могут превзойти скомпилированные языки программирования, такие как C, в определенных задачах. Это потому, что JVM имеет информацию во время выполнения и выполняет JIT-компиляцию при необходимости (я думаю).

(пример: http://benchmarksgame.alioth.debian.org/u32/performance.php?test=chameneosredux)

Есть ли что-нибудь подобное для скомпилированного языка? (меня интересует C в первую очередь)

После компиляции исходного кода разработчик запускает его и пытается имитировать типичную рабочую нагрузку. Инструмент собирает информацию о прогоне, а затем в соответствии с этими данными снова компилируется.

3 ответа

Решение

GCC имеет -fprofile-arcs

с man-страницы:

-fprofile-дуга
    Добавьте код, чтобы инструктировать дуги потока программы. Во время исполнения 
    программа записывает, сколько раз выполнялась каждая ветка и вызов и сколько 
    раз он взят или возвращается. Когда скомпилированная программа завершает работу, она сохраняет 
    данные в файл с именем auxname.gcda для каждого исходного файла. Данные могут быть 
    используется для направленной оптимизации профиля (-fbranch-вероятности), или для 
    анализ покрытия теста (-ftest-покрытие).

Я не думаю, что JVM когда-либо побеждал хорошо оптимизированный C-код.

Но чтобы сделать что-то подобное для c, вы ищете оптимизацию по профилю, где компилятор использует информацию времени выполнения из предыдущего запуска для повторной компиляции программы.

Да, есть некоторые инструменты, подобные этому, я думаю, что это известно как "оптимизация под руководством профилировщика".

Есть ряд оптимизаций. Важным является сокращение подкачки бэк-хранилища, а также использование вашего кеша кода. Многие современные процессоры имеют один кэш кода, может быть, второй уровень кеша кода, или второй унифицированный кэш данных и кода, может быть, кэш третьего уровня.

Самое простое, что можно сделать, это переместить все ваши наиболее часто используемые функции в одно место в исполняемом файле, скажем, в начале. Более сложным является перемещение менее часто используемых ветвей в какую-то совершенно другую часть файла.

Некоторые архитектуры набора команд, такие как PowerPC, имеют биты предсказания ветвления в своем машинном коде. Оптимизация под управлением профилировщика пытается установить их более выгодно.

Apple использовала это для семинара программистов Macintosh - для классической Mac OS - с помощью инструмента под названием "MrPlus". Я думаю, что GCC может сделать это. Я ожидаю, что LLVM может, но я не знаю как.

Другие вопросы по тегам