Компиляция с максимальными оптимизациями под определенный CPU

В Linux есть гораздо больший потенциал для настройки системы для себя в отличии от Windows. Многие сейчас имеют современные процессоры архитектуры i686 и конечно же хочется использовать максимум его возможностей и выжать из него все что можно. Я не утверждаю конечно но мне кажется что в Windows большинство софта собрано с минимальными оптимизациями кода. Ведь надо сохранить наибольшую совместимость поколений CPU и т.д. В данном контексте Linux имеет существенное превосходство которое позволяет вам собрать любую программу из исходных кодов с оптимальными флагами оптимизации.

Существует много source based дистрибутивов Linux в которых всю систему от /bin/bash до mplayer вы собираете сами — это Gentoo, Slackware… etc. Не буду начинать холивар, но генту мне кажется слишком красноглазой. Я не хочу собирать каждую приблуду из сорцов, поэтому использую золотую середину — Arch Linux. В Арче все пакеты из репозиториев собраны под i686 с небольшими оптимизациями. Но все же многим включая меня этого мало. Существует специальный перловый скрипт который дизасемблит бинарник и показывает количество использованных инструкций CPU (mmx sse sse2 ssse3 mssse4.1), другими словами показывает под какой CPU собран бинарник ну и конечно же показывает будет ли данный код использовать все инструкции вашего современного процессора который их несомненно поддерживает. Первый тест будет для pcmanfm из репов Arch Linux:

[kernel@arch My-scripts]$ ./check-native.sh /media4/Linux/ds/usr/bin/pcmanfm
Checking vendor_id string...
GenuineIntel Disassembling /media4/Linux/ds/usr/bin/pcmanfm, please wait...
i486:    45
i586:    0
ppro:   139
mmx:     0
sse:     0
sse2:    0
sse3:    0
sse4.1:  0
sse4.2:  0
/media4/Linux/ds/usr/bin/pcmanfm will run on Pentium Pro (i686 or pentiumpro) or higher processor.

Как видим данный бинарник может запускаться на i686 архитектуре и выше но не будет использовать mmx, sse, sse2, sse3. Но так как мы имеем скажем Core2 Duo который поддерживает набор инструкции CPU такие как sse, sse2, sse3 нам хочется чтоб программа тоже могла воспользоваться этими возможностями. Теперь смотрим используются ли эти инструкции при ручной сборке из исходников с определенными флагами.


[kernel@arch My-scripts]$ ./check-native.sh /usr/bin/pcmanfm
Checking vendor_id string...
GenuineIntel Disassembling /usr/bin/pcmanfm, please wait...
i486: 0
i586: 2
ppro: 178
mmx: 32
sse: 2
sse2: 32
sse3: 60
sse4.1: 0
sse4.2: 0
/usr/bin/pcmanfm will run on Pentium IV (pentium4) w/ SSE3 or higher processor.

Как вы видите эта же программа собранная по такому же PKGBUILD но с определенными флагами начинает использовать инструкции mmx, sse, sse2, sse3, что несомненно дает большую скорость выполнения кода. Есть конечно и другая сторона — увеличивается размер бинарника и собранные с такими оптимизациями программы дольше запускаются, но работаю быстрее. Итак для себя я набрал оптимальный набор флагов gcc с которыми софт нормально собирается (90%) и стабильно работает.

CFLAGS="-O2 -march=core2 --param l1-cache-size=32 --param l1-cache-line-size=32 --param l2-cache-size=4096 
-funroll-loops -ffast-math -fomit-frame-pointer -ftree-vectorize -pipe"

Версия gcc:

gcc версия 4.4.3 20100316 (prerelease) (GCC)

Сегодня было собрано ядро Linux с такими же агрессивными флагами и оно нормально собирается и работает. Об этом я напишу чуть позже, надо протестировать на стабильность.

Оцените статью