В чем разница между -O3 и (-O2 + флажками, которые man gcc говорит, что -O3 добавляет к -O2)? - PullRequest
27 голосов
/ 23 июня 2011

Недавно я получил сообщение об ошибке в программе, которая не может быть скомпилирована с ключом -O3 (см. https://github.com/cschwan/sage-on-gentoo/issues/66).). В частности, проблема заключается в том, что компиляция зависает в определенный момент. Проблема решается путем компиляции с помощью-O2 (я хорошо знаю, что программы, скомпилированные с -O3, могут быть повреждены, но я не знал, что -O3 может повесить компилятор). Если вы хотите воспроизвести проблему, запустите

wget http://perso.ens-lyon.fr/xavier.pujol/fplll/libfplll-3.0.12.tar.gz
tar -xf libfplll-3.0.12.tar.gz
cd libfplll-3.0.12
./configure CXXFLAGS="-O3"
make

Мне было интересно, почему -O3 зависает компилятор, и поэтому я попытался отследить проблему. Сначала я попытался выяснить разницу между -O2 между -O3. Страница man Gcc утверждает, что -O3 включает переключатели -O2и следующие (давайте назовем их x):

-finline-functions -funswitch-loops -fpredictive-commoning -fgcse-after-reload
-ftree-vectorize -fipa-cp-clone

Я проверил это, сравнив вывод gcc при вызове с -Q -O2 --help=optimizers и -Q -O3 --help=optimizers. Затем я планировал выборочно удалить переключателичтобы найти тот, который вызывает проблему. Однако, компиляция работает отлично с -O2 и дополнительными ключами, описанными выше, поэтому я заключаю

-O3 != -O2 x

Теперьмой вопрос : Кто-нибудь знает, есть ли еще разница между -O2 и -O3 (недокументированное?), кто-нибудь испытывал подобное поведение?Это может быть ошибка компилятора?

Ответы [ 2 ]

21 голосов
/ 23 июня 2011

Справочные страницы могут быть устаревшими, но вы можете найти фактические списки для O2 и O3.

Чтобы получить полный список ( почти , проверьте "обновление") из -f параметров оптимизациифактически используется, я предлагаю вам использовать -fverbose-asm -save-temps (или -fverbose-asm -S) - есть полный список вверху файла asm (* .s).

Для gcc-4.6.0 я получил x (разница между O2 и O3):

 -fgcse-after-reload
 -finline-functions
 -fipa-cp-clone
 -fpredictive-commoning
 -ftree-loop-distribute-patterns
 -ftree-vectorize
 -funswitch-loops

Другим источником информации для вашего вопроса являются источники GCC (файл gcc/opts.c и, возможно, gcc/common.opt) какgcc-4.6.0:

/* -O3 optimizations.  */
{ OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribute_patterns, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_fpredictive_commoning, NULL, 1 },
/* Inlining of functions reducing size is a good idea with -Os
   regardless of them being declared inline.  */
{ OPT_LEVELS_3_PLUS_AND_SIZE, OPT_finline_functions, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_ftree_vectorize, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 },

Я также проверил, проверяет ли gcc -On в других файлах (поиск символа cscope для x_optimize).

Единственное дополнительное использованиеn из опции -On сохраняет значение в макросе __OPTIMIZE__.Поэтому некоторые заголовки могут вести себя по-разному для значения этого макроса, равного 2 или 3.

ОБНОВЛЕНИЕ: В GCC WIKI есть вопросы :

  • " Является ли -O1 (-O2, -O3 или -Os) эквивалентным индивидуальным опциям оптимизации?"

Нет.Во-первых, отдельные параметры оптимизации (-f *) не включают оптимизацию, требуется параметр -Os или -Ox с x> 0.Во-вторых, флаги -Ox включают много оптимизаций, которые не контролируются ни одной отдельной опцией -f *. Не планируется добавлять отдельные опции для управления всеми этими оптимизациями.

  • " Какие конкретные флаги включены -O1 (-O2, -O3или -Os)?"

Зависит от платформы и версии GCC.Вы можете заставить GCC сообщить вам, какие флаги он включает, выполнив следующее:

touch empty.c
gcc -O1 -S -fverbose-asm empty.c
cat empty.s
3 голосов
/ 23 июня 2011

Если ваш компилятор зависает, тогда да - я бы расценил это как ошибку компилятора. У компиляторов тоже есть ошибки.

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

Это могут быть и другие вещи, например, Выполнение оптимизации просто занимает намного больше времени, или повышенный уровень оптимизации заставляет использовать больше памяти, и ваша система начинает загружаться.

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