Pull to refresh

Comments 53

Вполне нормально. Достаточно много серъезных компаний использует gcc без обсуждений, но колеблется между AMD и Intel серверами.
Потом делаются бенчмарки для AMD и Intel (gcc с соответствующими опциями для каждой архитектуры).
Так что, это больше раскрутка Intel как архитектуры для выполнения кода, так как они понимают что не все могут просто так перелезть с gcc на icc или другие компиляторы.
Разумно.

Я уж было подумал, что бригады чертей прямо в этот момент носятся туда-сюда в поисках причин внезапного заморозка у них дома…
"-flto" межмодульные оптимизации

Вот про этот режим я бы поподробнее расписал как это работает. И как с этим флагом собрать webkit, если 12 Gb оперативной памяти оказывается мало?
Никак. Но с ним можно собирать отдельные модули или использовать инкрементальную сборку. Хотя на практике мне это удалось использовать лишь один раз. Зато программа получилась в полтора раза компактнее и примерно на столько же быстрее. Но сколько было гемора…
Кстати, в новых версиях gcc всё стало попроще, и работает более менее сразу. Но большие проекты требуют излишне много памяти, хотя этому и есть простое объяснение.
Можно смешивать объектные файлы с внутренним представлением и обычные. Таким образом Вы сможете применить lto только к нужной части проекта. Например, только там где недостает inline или только к горячим модулям.
А вот это интересно. Спасибо, не знал!
А как в xcode скомпилировать код чтобы при этом _mh_execute_header.cpusubtype не выходил как CPU_SUBTYPE_386
Мне вот давно уже хотелось бы компилить на CPU_SUBTYPE_PENTIUM_4
только вот рецептами из вашей статьи воспользоваться не получилось
при попытке установить «Other С Flags» как -march=native код ваще не компилится с ошибкой:
Prefix.pch:1: error: bad value (native) for -march= switch
Prefix.pch:1: Bad value (native) for -mtune= switch
Он не умеет march=native. Фича только с gcc 4.3 появилась.
ясно. А может есть какой-либо другой way чтобы компилить для CPU_SUBTYPE_PENTIUM_4 на gcc 4.2?
Там gcc только как фронтенд к llvm. Настоящий gcc надо отдельно ставить.
Однако:
-O3: This is the highest level of optimization possible, and also the riskiest. It will take a longer time to compile your code with this option, and in fact it should not be used system-wide with gcc 4.x. The behavior of gcc has changed significantly since version 3.x. In 3.x, -O3 has been shown to lead to marginally faster execution times over -O2, but this is no longer the case with gcc 4.x. Compiling all your packages with -O3 will result in larger binaries that require more memory, and will significantly increase the odds of compilation failure or unexpected program behavior (including errors). The downsides outweigh the benefits; remember the principle of diminishing returns. Using -O3 is not recommended for gcc 4.x.

Отсюда: www.gentoo.org/doc/en/gcc-optimization.xml
Сборка генты и сборка собственного приложения — никак не связанные вещи.
Compiling all your packages your application with -O3 will result in larger binaries that require more memory, and will significantly increase the odds of compilation failure or unexpected program behavior (including errors).

Всё ещё актуально, по моему.
Однако, для своего приложения можно сделать тесты и при желании посмотреть ассемблерные листинги в критичных местах. Для all your packages — нет. Поэтому во многих числодробильных пакетах -O3/-Ofast есть во всех дистрибутивах, уже в оригинальном мейкфайле (не обязательно для всех файлов, естественно).
-O3
Optimize yet more. -O3 turns on all optimizations specified by -O2 and also turns on the -finline-functions, -funswitch-loops, -fpredictive-commoning, -fgcse-after-reload, -ftree-vectorize and -fipa-cp-clone options.

Взято с gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Optimize-Options.html

Согласен, что не так и много добавлено в сравнении с O2, но:
1. O3 включает векторизацию (в отдельных случаях это сильно разгоняет приложение).
2. Добавляет inline, что может и сократить код, если процедура объявлена static. Хотя чаще всего, конечно, увеличит как код, так и производительность.
O3 включает векторизацию (в отдельных случаях это сильно разгоняет приложение).

Недавно столкнулся с такой штукой — два вложенных цикла for:
for(i=0;i<x;i++) { for(k=0;k<16;k++) { s += a[k] + b[k] + a[k+1] + b[k+1];} a += y; b += y; }
O3 включает в себя развёртку циклов, которая до векторизации разворачивает внутренний цикл, после чего векторизатор не способен ничего сделать из-за кривого доступа к массиву. Без разворачивания внутренний цикл векторизуется, и на данном примере -O2 -ftree-vectorize ощутимо быстрее чем -O3
O3 включает в себя развёртку циклов

В gcc на O3 включается более агрессивная развертка циклов с маленьким и статическим числом итераций, так называемый «full peeling». Это очень полезная оптимизация для тех архитектур, где предсказатель переходов не всегда оптимален и стоимость промаха велика (в основном это касается мобильных устройств).
векторизатор не способен ничего сделать из-за кривого доступа к массиву

Для 4.7 это действительно так. В 4.8 уже поправлено, и все векторизуется. Релиз уже очень скоро.
Как workaround могу посоветовать Вам опцию контроля peeling:
--param max-completely-peel-times=2
в сочетании с -funroll-loops она должна максимально разогнать приведенный цикл.
В 4.8 уже поправлено, и все векторизуется.

Буду рад если в релизе это так, я проверял на 4.8 от конца сентября 2012. В идеале хотелось бы, чтобы при полностью развернутом внутреннем цикле внешний векторизовался, тогда это позволит вынести редукцию по сложению совсем вне циклов.
Было бы интересно увидеть сравнение по производительности icc т.е. насколько сами Intel могут приблизить gcc к icc :-)
От набора тестов очень зависит. На спеках сравнение будет сильно не в пользу gcc.
+1, пробовали как-то раз. На вычислительных бенчмарках gcc довольно сильно проигрывает, на большом коммерческом коде (в котором, впрочем, тоже очень много вычислений) уступает. Но это эксперименты двухгодичной давности, может быть, сейчас что-то изменилось.
А можно ли как-то систем-wide прописать настройку для ранее скомпилированного gcc без его пересборки?
configure может и подхватит, а вот сам gcc нет:
datacompboy@nuuzerpogodible:~$ CFLAGS=-march=native echo "int main(){return 0;}" | gcc -x c -v -Q -
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.7.2-4' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.7.2 (Debian 4.7.2-4) 
COLLECT_GCC_OPTIONS='-v' '-Q' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/4.7/cc1 -v -imultiarch x86_64-linux-gnu - -dumpbase - -mtune=generic -march=x86-64 -auxbase - -version -o /tmp/ccoRhjPC.s
Можно попробовать сделать обертку:
1. переименовать gcc, g++ и gfortran например в *.4_7
2. сделать исполняемый скрипт в gcc (в остальных по аналогии):
gcc.4_7 $GCC_CFLAGS "$@"
Если gcc пускается с полным путем, то надо и полный путь к gcc.4_7 указать в скрипте.
3. А потом можно и export GCC_CFLAGS
> Вы всегда можете узнать все опции, передаваемые при запуске GCC, а также его внутренние опции при помощи команды:
>
> echo "int main {return 0;}" | gcc [OPTIONS] -x c -v -Q -

Хм, у меня эта команда выдает вот что:

gcc: error: [OPTIONS]: Нет такого файла или каталога Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/i486-linux-gnu/4.7/lto-wrapper Target: i486-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 4.7.1-7' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --enable-targets=all --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu Thread model: posix gcc version 4.7.1 (Debian 4.7.1-7)

И где тут стандартные опции можно увидеть?
echo "int main {return 0;}" | gcc -O1 -x c -v -Q -

echo "int main {return 0;}" | gcc -O2 -x c -v -Q -
Под [OPTIONS] имелись ввиду Ваши опции, например, O2 или O3. Удобство в том, что упомянутая команда выводит:
1. Опции по дефолту (-march=, -mfpmath=)
2. Расшифровывает опции -O2, -O3, -Ofast и другие, которые могут отличаться для разных бранчей. GCC компиляторы в поставке операционных систем, тулов для разработки могут отличаться от основного и подключать разные оптимизации при тех же уровнях оптимизации.
> Под [OPTIONS] имелись ввиду Ваши опции, например, O2 или O3.

Не понял, чтобы увидеть опции, надо написать опции???
Не понял, чтобы увидеть опции, надо написать опции???

Да. Указанная технология раскрывает внутренние опции компилятора. Например, "-O2" это комплекс оптимизаций, который может отличаться для разных бранчей.
LTO появился сравнительно недавно, до LTO я пользовался PGO (Profile-guided optimization)
habrahabr.ru/post/138132/
Эта штука СИЛЬНО ускоряет приложения и является (по моему мнению) необходимой в embedded-среде.
Как раз вчера задавался этим вопросом – с какими параметрами по умолчанию скомпилированны в rpm apache/mysql/php/apc и что из них можно выжать, перекомпилировав их с максимальными флагами с помощью gcc или тем более ICC (Intel, как вы могли в своём блоге упомянуть icc в сравнении с gcc? )

Здесь (http://vbtechsupport.com/715/ ) есть некий пример компиляции Mysql под Intel через gcc, но приведены совсем другие флаги ( –with-fast-mutexes, –with-aria-tmp-tables, –with-atomic-ops=smp –mtune=nocona. ) и совсем не упоминаются -Ofast -flto -march=native -funroll-loops. Кто более прав в этом случае?

И хотелось бы задать вопрос Intel: не хотите ли сделать свой репозитарий пакетов LAMP, сделанный через icc с максимальными оптимизациями под i7/xeon? Весь мир бы вам спасибо сказал за бесплатные свежие +5 — +20% производительности.
Intel, как вы могли в своём блоге упомянуть icc в сравнении с gcc?

Вроде не упоминали. Сатья про GCC только.
vbtechsupport.com/715/

В указанной статье речь идет о многопоточности. Здесь речь идет о последовательном коде.
–with-fast-mutexes, –with-aria-tmp-tables, –with-atomic-ops=smp

Скорее напоминает опции конфигурации и не противоречит -Ofast -flto -funroll-loops.
Но Вы правы, для каждого отдельного приложения оптимальный набор опций может быть свой.
И хотелось бы задать вопрос Intel

Ваш вопрос касается icc и лучше задать его в разделе Вопросы.
Цель данной статьи помочь пользователям GCC на x86 ускорить свои приложения. Что касается сравнения GCC и ICC, то лучше чтобы это делали независимые люди.
И хотелось бы задать вопрос Intel: не хотите ли сделать свой репозитарий пакетов LAMP, сделанный через icc с максимальными оптимизациями под i7/xeon? Весь мир бы вам спасибо сказал за бесплатные свежие +5 — +20% производительности.


Раз нет таких готовых сборок, значит похвастаться не чем.
В LAMP нет какой-то математики навороченной, да и много там float/double? Видимо будет 5% прироста, а тогда все узнают что icc VC gcc это 5% и всё, маркетинг проиграет.
Речь ведь не только о float/double, но и обо всех длительных оптимизациях, о которых рассказано в статье. Не каждый ведь будет собирать с LTO и PDO по несколько часов на десятках гигабайт памяти, а так были бы готовые рабочие быстрые пакеты. Централизированный билд с максимально производительными настройками и автоматизированное тестирование упростило бы жизнь многим людям.
Впрочем в том же mysql хватает целочисленной математики, подсчёт различных hash, b-tree и прочего, не зря есть даже экспериментальные проекты реляционных баз данных для GPGPU
К сожалению, большинство описанной в статье информации относится не к GCC, а к компиляции для одной конкретной архитектуры х86. Особенно x87, SSE2 и так далее.
А для мобильных приложений, которые многократно упомянуты не к месту, актуальна оптимизация для ARM, например включение инструкций ARMv7 и NEON.
А для мобильных приложений, которые многократно упомянуты не к месту

Ну почему же не к месту? Вот есть примеры:
habrahabr.ru/company/intel/blog/150099/
habrahabr.ru/company/intel/blog/153183/

Для ARM, наверное, есть свои оптимизации, но это тема для другой статьи.
Думаю необходимо отметить, что агрессивные оптимизации типа ffast-math могут поменять результаты вычислений. И зачастую получается, что программа скомпилированная на разных платформах выдаёт разные цифры. Так что, например, в научных программах такие опции не рекомендуют употреблять.
Сразу видно, что это перевод, причём очень плохой. Читать невозможно
Не знаю что считать первоисточником (ибо автор один), но я действительно публиковал английский вариант статьи здесь:
software.intel.com/en-us/blogs/2012/09/26/gcc-x86-performance-hints
Так что это не совсем перевод. Просто очень многие сложившиеся технические термины тяжело сформулировать на русском языке.
Эээ, то есть автор текста на обоих языках ты?

Итак, текст запутан, воспринимается трудно.

Вот например, (1): «По умолчанию GCC использует опцию, заданную при его конфигурации». Какая опция имеется в виду? "-march=native"? В таком случае возможны два варианта: либо такая опция есть, либо её нет. Тогда нужно написать так: «По умолчанию GCC использует опцию -march=native, если она была задана при конфигурации». А может быть, имелось в виду не это? Может имелась в виду опция -march=X, где вместо X могут быть разные параметры? А может быть, имелись в виду просто любые опции? То есть просто при конфигурации можно задать любые опции, которые будут добавляться к командной строке? Тогда нужно было написать «опции», а не «опция». В любом случае, из текста это непонятно.

Скорее всего, имелось в виду -march=X. Хорошо, тогда так и надо было написать: «По умолчанию GCC использует тот параметр к опции -march, который указан при конфигурации». Во! Вот так намного понятнее.

И вообще, в первых нескольких абзацах я всё время вижу опции, опции, опции. В глазах ребит от этого слова.

Текст скучный, сухой, неинтересный :)
К сожалению, -flto дает увеличение производительности не всегда, или мало.
Больше эффекта можно получить от так называемого PGO (Profile-guided optimization), про него писали здесь.
Для использования PGO необходимо собрать статистику использования кода, а затем компилятор сделает оптимизации под заданный кейс использования программы.
PGO это действительно сильный инструмент для поднятия производительности, однако, и более рисковый. Очень многое зависит от тренировочных данных. Подбор таких данных — сложная задача.
PGO существенно замедляет сборку. LTO же позволяет распараллеливать сборку -flto=N и свести потери к минимуму, а иногда и ускориться.
Собственно, никто не мешает использовать и то, и другое.
Так что, если PGO ускоряет Ваш код и удобно в использовании, смело добавляйте его к -Ofast -flto -march=native (-funroll-loops по вкусу).
Спасибо за подсказку про распараллеливание сборки -flto=N (не всегда достаточно make -j N), очень долгая сборка у меня была одной из причин отказа от LTO, т.к. результата было мизер, а время сборки увеличилось в 2-3 раза.
Для PGO я подаю «боевые» данные.
Sign up to leave a comment.