HOWTO Использование CFLAGS для оптимизации собранных программ
Материал из Gentoo Linux Wiki
Содержание |
[править] Для чего все это надо?
Стремление выжать из своего компьютера максимум производительности есть в каждом, ну почти в каждом ;-). Особенно его много в русских линуксоидах Gentoo'шниках ;) Мы попытаемся путем изменения флагов оптимизации ускорить работу приложений нашей системы. ВНИМАНИЕ Некоторые флаги могут сделать приложения нестабильными, так что нужно быть аккуратным.
[править] Оптимизация
[править] Переменная окружения CFLAGS
- Для указания параметров оптимизации компилятору GCC, используется переменная окружения CFLAGS. Эта переменная определена в /etc/make.conf, её можно изменить двумя способами:
- Отредактировать эту переменную в /etc/make.conf;
- Экспортировать ее в окружение (emerge будет использовать эти параметры, но каждый раз выполнять export неудобно):
export CFLAGS='параметры оптимизации'
[править] Уровни оптимизации
Для gcc версий 3.x и выше существует только 5 уровней оптимизации: -O0 (без оптимизации), -O1, -O2 и -O3 (O3 - самый высокий уровень), а так же -Os.
- Примечание: Если вы используете несколько -O опций, то только последняя объявленная будет оказывать влияние на процесс компиляции.
[править] -O0
- Отключает оптимизацию. Только переменные, обьявленные register, сохраняются в регистрах.
[править] -O(-O1)
- Включает оптимизацию. Пытается уменьшить размер кода и ускорить работу программы. Соответственно увеличивается время компиляции. При указании -O активируются следующие флаги: -fthread-jumps, -fdefer-pop.
- На машинах, у которых есть слоты задержки, включается опция -fdelayed-branch.
- На тех машинах, которые способны поддерживать отладку даже без указателя на стек функции, также включается опция -fomit-frame-pointer.
- На других машинах могут быть включены и другие флаги.
[править] -O2
- Оптимизирует еще больше. GCC выполняет почти все поддерживаемые оптимизации, которые не включают уменьшение времени исполнения за счет увеличения длины кода. Компилятор не выполняет раскрутку циклов или подстановку функций, когда вы указываете -O2. По сравнению с -O, эта опция увеличивает как время компиляции, так и эффективность сгенерированного кода.
- -O2 включает все флаги оптимизации наследованые от -O. Также включает следущие флаги оптимизации:
-fforce-mem -foptimize-sibling-calls -fstrength-reduce -fcse-follow-jumps -fcse-skip-blocks -frerun-cse-after-loop -frerun-loop-opt -fgcse -fgcse-lm -fgcse-sm -fgcse-las -fdelete-null-pointer-checks -fexpensive-optimizations -fregmove -fschedule-insns -fschedule-insns2 -fsched-interblock -fsched-spec -fcaller-saves -fpeephole2 -freorder-blocks -fre-order-functions -fstrict-aliasing -funit-at-a-time -falign-functions -falign-jumps -falign-loops -falign-labels -fcrossjumping
[править] -O3
- Оптимизирует еще немного. Включает все оптимизации -O2 и также включает флаг -finline-functions и -fweb.
Примечание: Как правило, это отрицательно сказывается на времени компиляции, а иногда и на производительности программ.
[править] -Os
- Включает оптимизацию по размеру. -Os флаг активирует все флаги оптимизации из -O2, в основном те, которые не увеличивают размер выходного файла. В дальнейшем выполняются оптимизации по уменьшению размера кода.
- -Os выключает следущие флаги оптимизации: -falign-functions, -falign-jumps, -falign-loop, -falign-labels, -freorder-blocks, -fprefetch-loop-arrays.
Примечание: Более полное описание флагов -Ox, -fflag смотрите в man gcc
[править] Оптимизация под тип процессора
Не все процессоры одинаковы,поэтому давайте укажем компилятору на наш тип процессора.Для этого есть опции -mtune и -march.Отличие в том,что с опцией -mtune компилятор сделает код,который будет совместим с более младшими моделями процессора,в то время как с -march этого не происходит.Вот список возможных значений для данных опций:
- i386
- i486
- i586
- i686
- pentium
- pentium-mmx
- pentiumpro
- pentium2
- pentium3
- pentium4
- pentium-m
- prescott
- nocona
- core2 (для GCC >= 4.3)
- k6
- k8
- k6-2 (не рекомендуется ставить, из-за багов в компиляторе, заменять на i686)
- k6-3
- athlon
- athlon-tbird
- athlon-4
- athlon-xp
- athlon-mp
- athlon64
- opteron
- winchip-c6
- winchip2
- c3.
- native (GCC >= 4.2 автоматически определяет возможности процессора по /proc/cpuinfo)
Внимание! pentium-m - это аналог для pentium3. Если процессор в вашем ноутбуке Mobile Intel Pentium 4 - M, то нужно ставить опцию pentium4 или pentium4m (они равнозначны)
Неоднозначный вопрос с серией Atom. Нативная поддержка обещается только в gcc 4.5 - а пока только экперементировать на свой страх и риск. На Atom 330 лучше ставить core2 - проверено, быстрее чем prescott.
[править] Выбор оптимальных параметров
Чтобы узнать какие CFLAGS можно использовать для вашего процессора введите gcc -Q --help=optimizers|grep enable
Но для этого есть еще и очень интересная утилита. emerge acovea
Правда существующие профили рассчитаны только на pentium 3/4, и на gcc 3.3/3.4, Но в принципе добавить свою конфигурацию тоже не составляет труда. Также рекомендуется добавить в конфигурацию опции -ftracer и -mfpmath=sse. В некоторых случаях они дают значительный прирост производительности сгенерированного кода.
После чего вызываем утилиту runacovea -config gcc33_pentium3.acovea -bench evobench.c Ждем несколько часов и получаем оптимальные флаги компиляции.
Возможны различные тесты, которые хранятся в каталоге /usr/share/acovea/benchmarks, И различные конфигурации платформы /usr/share/acovea/config, к которым при желании можно добавить свою.
Но...
К сожалению автор сей замечательной утилиты не советует использовать результаты работы acovea для системы в целом. Вот что он пишет:
Should I use Acovea to optimize the complete build of a Linux system (aka, "the Gentoo question")? No. ... Results from running Acovea against a few algorithms should NOT be applied across a broad spectrum of applications. For my Gentoo-based systems, I don't set the value of make.conf's CFLAGS based on Acovea results; I build specific, time-critical applications using algorithm-specific options.
[править] Указание CFLAGS для отдельных пакетов
Для любых пакетов можно указать CFLAGS, которые будут обладать большим приоритетом чем те, что указаны в make.conf. Делается это в /etc/portage/env. Вот пример содержимого каталога env:
/etc/portage/env/ ├── net-libs │ └── xulrunner ├── www-client └── mozilla-firefox
В файлах xulrunner и mozilla-firefox указываются нужные CFLAGS тем же образом, что и в make.conf.