Подтвердить что ты не робот

В чем разница между уровнями оптимизации gcc?

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

Ответ 3

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

Ответ 4

Sidenote:

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

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

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

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

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