Я бы рекомендовал скомпилировать новый код с -std=gnu11
или -std=c11
при необходимости. Отключение всех -Wall
предупреждений, как правило, хорошая идея, IIRC. -Wextra
предупреждает о некоторых вещах, которые вы, возможно, не захотите изменить.
Хороший способ проверить, как что-то компилируется, чтобы посмотреть на выход asm компилятора. http://gcc.godbolt.org/ отлично отображает выход ASM (удаление шума). Включение некоторых ключевых функций и просмотр того, что делают другие версии компилятора, полезны, если вы вообще понимаете asm.
Используйте новую версию компилятора. gcc и clang значительно улучшились в новых версиях. gcc 5.3 и clang 3.8 - текущие выпуски. В некоторых случаях gcc5 делает код лучше, чем gcc 4.9.3.
Если вам нужен только двоичный файл для запуска на вашей машине, вы должны использовать -O3 -march=native
.
Если вам нужны бинарные файлы для запуска на других машинах, выберите базовую линию для расширений набора инструкций, например, -mssse3 -mpopcnt
. Вы можете использовать -mtune=haswell
для оптимизации для Haswell даже при создании кода, который по-прежнему работает на старых процессорах (как определено -march
).
Если ваша программа не зависит от строгого округления поведения FP, используйте -ffast-math
.Если это так, вы, как правило, можете использовать -fno-math-errno
и так далее, без включения -funsafe-math-optimizations
. Некоторый код FP может получить big ускорение от быстрой математики, например, авто-векторизация.
Если вы можете с пользой сделать пробный запуск вашей программы, который осуществляет большинство путей коды, которые должны быть оптимизированы для реального запуска, а затем использовать профиль направленной оптимизацию:
gcc -fprofile-generate -Wall -Wextra -std=gnu11 -O3 -ffast-math -march=native -fwhole-program *.c -o my_program
./my_program -option1 < test_input1
./my_program -option2 < test_input2
gcc -fprofile-use -Wall -Wextra -std=gnu11 -O3 -ffast-math -march=native -fwhole-program *.c -o my_program
-fprofile-use
включает -funroll-loops
, так как у него достаточно информации, чтобы решить, когда нужно развернуть. Развертывание петель по всему месту может ухудшить ситуацию. Тем не менее, стоит попробовать -funroll-loops
, чтобы узнать, помогает ли это.
Если ваши тестовые прогоны не охватывают все кодовые пути, то некоторые важные будут отмечены как «холодные» и оптимизированы меньше.
-O3
позволяет автоматической векторизации, который -O2
не делает. Это может дать большие ускорений
-fwhole-program
позволяет кросс-файл встраивание, но работает только тогда, когда вы кладете все исходные файлы на один GCC командной строки. -flto
- это еще один способ получить тот же эффект. (Оптимизация времени соединения). clang поддерживает -flto
, но не -fwhole-program
.
был по умолчанию на данный момент для x86-64 и совсем недавно для x86 (32 бит).
Как GCC, попробуйте скомпилировать свою программу с лязгом. Иногда Clang делает лучший код, чем gcc, иногда хуже. Попробуйте оба теста.
'-ansi' указывает стандарт C89/C90; '-std = c99' указывает стандарт 1999 года (и' -std = c11' указывает текущий стандарт 2011 года). Нецелесообразно использовать их вместе. –
Оптимизация специфична для компилятора. Вы, кажется, используете параметры компилятора в стиле GCC, но другие компиляторы принимают одинаковые флаги. Отметьте этот вопрос с помощью компилятора C, который вы используете, если вы хотите иметь значимые ответы о флажках, влияющих на оптимизацию для реализации C. –
В случае использования компилятора GCC [этот ответ] (http://stackoverflow.com/a/1778700/6166067) может оказаться полезным. – aprelev