В чем разница между уровнями оптимизации gcc? - PullRequest
24 голосов
/ 18 сентября 2008

В чем разница между разными уровнями оптимизации в GCC? Предполагая, что мне не нужны какие-либо средства отладки, почему бы мне просто не использовать самый высокий уровень оптимизации, доступный мне? Обязательно ли более высокий уровень оптимизации (то есть доказуемо) генерирует более быструю программу?

Ответы [ 4 ]

14 голосов
/ 18 сентября 2008

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

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

Как последнее замечание, проект GNU компилирует все свои программы в -O2 по умолчанию , а -O2 довольно распространен в других местах.

13 голосов
/ 18 сентября 2008

Как правило, уровни оптимизации выше -O2 (просто -O3 для gcc, но у других компиляторов выше) включают в себя оптимизации, которые могут увеличить размер вашего кода. Это включает в себя такие вещи, как развертывание цикла, большое количество вставок, заполнение для выравнивания независимо от размера и т. Д. Другие компиляторы предлагают векторизацию и межпроцедурную оптимизацию на уровнях выше -O3, а также некоторые оптимизации, которые могут значительно улучшить скорость стоимость правильности (например, использование более быстрых, менее точных математических процедур). Проверьте документы, прежде чем использовать эти вещи.

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

3 голосов
/ 18 сентября 2008

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

1 голос
/ 30 сентября 2008

Sidenote:

Довольно сложно точно предсказать, какие флаги включены глобальными директивами -O в командной строке gcc для разных версий и платформ, и вся документация на сайте GCC, скорее всего, быстро устареет или не охватит внутренности компилятора достаточно подробно.

Вот простой способ точно проверить, что происходит на вашей конкретной установке, когда вы используете один из -O флагов и другие -f флаги и / или их комбинации:

  1. Создать где-нибудь пустой исходный файл:
    touch dummy.c
  2. Запустите его, хотя компилятор проходит, как обычно, со всеми флагами -O, -f и / или -m, которые вы обычно используете, но добавляя -Q -v в командную строку:
    gcc -c -Q -v dummy.c
  3. Проверьте сгенерированный вывод, возможно, сохранив его для другого прогона.
  4. Измените командную строку по своему вкусу, удалите сгенерированный объектный файл с помощью rm -f dummy.o и снова запустите.

Кроме того, всегда имейте в виду, что, с точки зрения пуриста, большинство нетривиальных оптимизаций генерирует «сломанный» код (где сломанный определяется как отклонение от оптимального пути в угловых случаях), поэтому выбирайте, стоит ли Включение определенного набора механизмов оптимизации иногда сводится к выбору уровня корректности для вывода компилятора. В оптимизаторе любого компилятора всегда есть (и в настоящее время есть) ошибки - просто проверьте список рассылки GCC и Bugzilla для некоторых примеров. Оптимизацию компилятора следует использовать только после фактического выполнения измерений, поскольку выгода от

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