Ускорить скомпилированные программы, используя информацию времени выполнения, как, например, 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 может, но я не знаю как.