Оптимизатор VS2008 C ++ иногда генерирует более медленный код? - PullRequest
3 голосов
/ 03 марта 2011

Исходя из предыдущего вопроса , я поиграл с настройками оптимизатора в моей сборке релиза, чтобы увидеть, какие преимущества можно извлечь из использования оптимизации компилятора. До сих пор я использовал / Ob1 (только inline, где inline явно указан) и / Oi (Включить встроенные функции). Я попытался изменить это, чтобы включить / Ot (благоприятный быстрый код), / Oy (пропустить указатели фреймов) и / Ob2 (встроенный любой подходящий), и, к моему удивлению, набор регрессии, который занимал 2 часа 58 минут, теперь занял 3 часа 16 минут. Мое первое предположение состояло в том, что мое собственное встраивание было более агрессивным, чем компилятор, но переход от / Ob2 к / Ob1 только улучшил ситуацию до 3h12m. Я все еще запускаю больше тестов, но может показаться, что в некоторых случаях / Ot (поддержка быстрого кода) на самом деле замедляет работу. Программное обеспечение является многопоточным и требует значительных вычислений (моделирование поверхностей, манипуляции и визуализация), и уже было в значительной степени оптимизировано вручную на основе результатов профилировщика. Программа также работает с большими объемами данных и довольно часто использует #pragma pack (4).

Так вот вопросы. Для оптимизированной вручную программы может ли оптимизация компилятора в VS2008 принести больше вреда, чем пользы? Иными словами, существуют ли известные документированные сценарии, в которых оптимизация компилятора снижает производительность? (Нет. Профилирование оптимизированного компилятором кода является болезненным, поэтому до настоящего времени профилирование выполнялось для неоптимизированного кода).

Редактировать Согласно советам Коди Грея и других, я добавил / O2 в настройки оптимизации и повторно выполнил мой набор тестов. Это привело к времени выполнения 3 ч 01, которое было сопоставимо с минимально оптимизированным прогоном. Учитывая (немного устаревшие) инструкции MSDN по оптимизации и публикацию из GOZ, я собираюсь проверить / O1, чтобы увидеть, действительно ли меньше в моем случае быстрее. Обратите внимание, что текущий EXE-файл составляет около 11 МБ. Я также попробую собрать VS2010 вместе и посмотрю, как это будет.

Edit2 С / O1 время выполнения составило 3 часа, а exe-файл 11 Мб был на 62k меньше. Обратите внимание, что причина этого и предыдущего связанного сообщения заключалась в том, чтобы проверить, перевешивают ли преимущества включения оптимизации компилятора недостатки с точки зрения профилирования и отладки. В данном конкретном случае они, по-видимому, не являются таковыми, хотя я признаюсь, что был удивлен, что ни одна из попытавшихся комбинаций не принесла какого-либо преимущества и некоторого ощутимого снижения производительности. FWIW, согласно этому предыдущему потоку , я, как правило, делаю большую часть своей оптимизации во время разработки и использую профилировщик в основном для проверки предположений проектирования, я думаю, что я буду придерживаться этого подхода. У меня будет последний финал VS2010 с включенной оптимизацией всей программы, и я оставлю все как есть.

Спасибо за все отзывы!

Ответы [ 3 ]

4 голосов
/ 03 марта 2011

Документация для /Ot состояний:

Если вы используете /Os или /Ot, то вы также должны указать /Og для оптимизации кода.

Так что вы, возможно, захотите всегда проходить /Og с /Ot в своих тестах.

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

2 голосов
/ 03 марта 2011

Хорошо известно, что favour fast code не всегда быстрее, чем favour small code. Эвристика компилятора не всезнающая и может ошибаться. В некоторых случаях меньший код работает быстрее, чем более быстрый.

Используйте /O2 для самого быстрого кода - компилятор лучше вас знает, как могут взаимодействовать различные настройки.

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

Вы также можете посмотреть на использование Profile Guided Optimization, которая поможет оптимизатору компилятора в некоторых впечатляющих модах.

2 голосов
/ 03 марта 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...