Как инструментальный исполняемый файл GCC может быть быстрее неинструментированного?
Я сравниваю издержки GCC Profile-Guided Optimization с тестами SPEC. У меня есть странные результаты с некоторыми тестами. На самом деле, два моих теста работают быстрее, когда есть инструменты.
Обычный исполняемый файл компилируется с помощью: -g -O2 -march=native
Инструментальный исполняемый файл компилируется с помощью: -g -O2 -march=native -fprofile-generate -fno-vpt
Я использую GCC 4.7 (если быть точным, в ветке Google). Компьютер, на котором запущен тест, оснащен процессором Intel® R Xeon® E5-2650 0 @ 2,00 ГГц.
bwaves - это тест Fortran и libquantum
Вот результаты:
bwaves-normal: 712.14
bwaves-instrumented: 697.22
=> ~2% faster
libquantum-normal: 463.88
libquantum-instrumented: 449.05
=> ~3.2% faster
Я запускал тесты несколько раз, думая, что это может быть проблемой на моей машине, но каждый раз я их подтверждал.
Я бы понял, что в некоторых программах очень небольшие накладные расходы, но я не вижу причин для улучшения.
Итак, мой вопрос: как инструментальный исполняемый файл GCC может быть быстрее оптимизированного нормального?
Спасибо
2 ответа
Я могу думать о двух возможностях, связанных с кешем.
Во-первых, приращение счетчика "согревает" некоторые важные строки кэша. Во-вторых, добавление структур, требуемых инструментами, приводит к тому, что некоторые сильно используемые массивы или переменные попадают в разные строки кэша.
Другая проблема заключается в том, что профилирование / увеличение счетчика не должно происходить каждый раз в цикле for - если в цикле нет 'break' или 'return', компилятору разрешается оптимизировать приращение вне цикла.
Глядя на документацию GCC, выглядит -fprofile-generate
действительно активирует некоторые специфические преобразования кода, чтобы сделать профилирование проще / дешевле, поэтому инструментальный код на самом деле не является оригинальным кодом + инструментарий. Изменения могут сделать код быстрее, а добавление кода также изменит поведение кэширования. Трудно понять, не увидев код обидчика. И из-за моего (давным-давно) дурачения с LCC, когда профилирование выполняется интеллектуально, оно включает удивительно небольшие изменения кода.
Просто любопытство: как код, скомпилированный с учетом профиля в расчете стоимости, по сравнению с вышеупомянутым?