Хочу оптимизировать программу и либы к ней прилягающие по скорости, все компилиться под gcc 4.0 на MacOSX, проекты под XCode.
Есть такая опция -03 таже есть не менее чудесная Unroll loop. Стоит ли их вместе использовать?
Ещё вопрос есть ли у gcc аналог ms-овтовского _froceinline ?
Также может кто другие ключики или опиции проекта включить подскажет?
Здравствуйте, nen777w, Вы писали:
N>Хочу оптимизировать программу и либы к ней прилягающие по скорости, все компилиться под gcc 4.0 на MacOSX, проекты под XCode. N>Есть такая опция -03 таже есть не менее чудесная Unroll loop. Стоит ли их вместе использовать?
-O3 не всегда дает хороший результат... в зависимости от проекта оно может помочь а может и наоборот сделать код более тормознытым чем под -O2...
N>Ещё вопрос есть ли у gcc аналог ms-овтовского _froceinline ?
не нада ничо форсить... gcc достаточно умен сам для этого... особена на -O2/-O3
N>Также может кто другие ключики или опиции проекта включить подскажет?
оч хороший глючик -fomit-frame-pointer -- оч заментна порой ушустряет код...
конечно же нада добавлять -march= со своей архитектурой
-ftree-vectorize -- для gcc 4.x включает автовекторизацию
ну -pipe мона добавить для слегка более шустрой компиляции
в принципе как многие те конечно же скажут, оптимайзить нада алгоритмы на основании данных профайлера
(как мне кажется ты пытаешься выжать максимум из своего проекта -- ok, идем дальше...
при определенных обстоятельствах (если ты сможешь запускать свою прогу так чтоб она прошла по как можно большему числу веток управления) можно использовать т.н. profile driven optimization. Суть в следующем компилимся со спец ключиками (типа этих: -fprofile-arcs, -fprofile-values, -ftest-coverage), запускаем свою прогу и гоняем ее как можно дольше чтоб набрать статистику (буит слита в спец файлики). потом компилим свою прогу опять с ключиком -fprofile-use и тогда оптимизатор буит использовать набранную статистику в своих оптимизационных целях
ну и наканец для маньяков есь проект Acovea -- Analysis of Compiler Options via Evolutionary Algorithm. Как видна из названия штука подбирает генетическим алгоритмом ключики генерящие в твоей именна проге наиболее оптимальный код
Здравствуйте, nen777w, Вы писали:
N>Ещё вопрос есть ли у gcc аналог ms-овтовского _froceinline ?
__attribute__((always_inline))
Дела с этим имел мало, но сомневаюсь, что GCC умён во всех случаях — в моём единственном 3.4(?) версия не справилась. Помню только, что фича убрала где-то 200кб (около 20%) лишнего бинарного кода.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, gear nuke, Вы писали:
GN>Здравствуйте, nen777w, Вы писали:
N>>Ещё вопрос есть ли у gcc аналог ms-овтовского _froceinline ?
GN>__attribute__((always_inline))
GN>Дела с этим имел мало, но сомневаюсь, что GCC умён во всех случаях — в моём единственном 3.4(?) версия не справилась. Помню только, что фича убрала где-то 200кб (около 20%) лишнего бинарного кода.
Я правильно понял что при применении __attribute__((always_inline)) код сократился ев 20%? Если "да" то как это?
Вызов функции — как минимум call (5 байтов на x86) + обычно загрузка параметров в регистры\стек. Да еще и в самой функции пролог\эпилог. Ну и оптимизировать заинлайненую функцию еще немного удаётся обычно. Все функции вызывались исключительно однократно, подозреваю, что у GCC такой же тупой эвристик, как в MSVC — смотрит на размер функции, и при превышении порога отключает её инлайн.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, gear nuke, Вы писали:
GN>Вызов функции — как минимум call (5 байтов на x86) + обычно загрузка параметров в регистры\стек. Да еще и в самой функции пролог\эпилог. Ну и оптимизировать заинлайненую функцию еще немного удаётся обычно. Все функции вызывались исключительно однократно, подозреваю, что у GCC такой же тупой эвристик, как в MSVC — смотрит на размер функции, и при превышении порога отключает её инлайн.
inline не всегда дает улучшение кода. В частности потому, что распределение регистров у gcc лучше работает на небольших функциях (вернее, на функциях, которым регистров хватает, существенно количество переменных и повторяющихся подвыражений, значение которых gcc может захотеть сохранить в регистре).
Здравствуйте, nen777w, Вы писали:
N>Хочу оптимизировать программу и либы к ней прилягающие по скорости, все компилиться под gcc 4.0 на MacOSX, проекты под XCode. N>Есть такая опция -03 таже есть не менее чудесная Unroll loop. Стоит ли их вместе использовать?
Не существует общего ответа. В разных случаях разное сочетание опций может оказаться оптимальным.
У меня, например, был случай, когда наилучший результат давала опция -Os (оптимизация по размеру). Связано это было с тем, что у процессора (это был ARM, а не x86) был очень маленький кеш, и у машинки была очень медленная память. Соответственно, для более компактного кода меньше времени уходило на его загрузку в "голову" процессора.
Тоже самое можно сказать про MSVC. Я думаю, что это "обман зрения" в большенстветве случаев. Ведь перед вызовом этих функций, используемые в них "свободные" регистры необхдимо сохранить (на стеке). Сама функция получается лучше, но вызывающий её код хуже. При инлайне лишние операции исключаются. С другой стороны, при интенсивном инлайне увеличивается потребление ресурсов компилятором — как поведёт себя конкретный экземпляр сказать трудно, возможно пропустит некоторую оптимизацию, а возможно вообще ничего не сможет скомпилировать, как кстати и было со всеми остальными компиляторами на том коде
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, Pzz, Вы писали:
Pzz>У меня, например, был случай, когда наилучший результат давала опция -Os (оптимизация по размеру). Связано это было с тем, что у процессора (это был ARM, а не x86) был очень маленький кеш, и у машинки была очень медленная память. Соответственно, для более компактного кода меньше времени уходило на его загрузку в "голову" процессора.
Это верно и для x86, компактный код в общем случае лучше по тем же самым причинам, про это в мануалах от AMD и Intel явно написано. Я как-то был неприятно удивлён, когда взял несколько реализации криптоалгоритмов, свернул развёрнытые циклы и увидел заметный прирост в скорости — воистину, premature optimization is the root of all evil.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, gear nuke, Вы писали:
GN>Здравствуйте, c-smile,
GN>Вызов функции — как минимум call (5 байтов на x86) + обычно загрузка параметров в регистры\стек. Да еще и в самой функции пролог\эпилог. Ну и оптимизировать заинлайненую функцию еще немного удаётся обычно. Все функции вызывались исключительно однократно, подозреваю, что у GCC такой же тупой эвристик, как в MSVC — смотрит на размер функции, и при превышении порога отключает её инлайн.
инлайнутые функции ограничены по умолчанию довольно большим сайзом!
сморим в `info gcc`:
`-finline-limit=N'
By default, GCC limits the size of functions that can be inlined.
This flag allows the control of this limit for functions that are
explicitly marked as inline (i.e., marked with the inline keyword
or defined within the class definition in c++). N is the size of
functions that can be inlined in number of pseudo instructions
(not counting parameter handling). The default value of N is 600.
Increasing this value can result in more inlined code at the cost
of compilation time and memory consumption. Decreasing usually
makes the compilation faster and less code will be inlined (which
presumably means slower programs). This option is particularly
useful for programs that use inlining heavily such as those based
on recursive templates with C++.
кроме того есть спец ключик: -finline-functions-called-once
ну и добавление -fomit-frame-pointer упрощает пролог
У MSVC 2003 — где-то 25 байт + если вызовы имеют вложенность больше 3х, то простые функции может не инлайнить
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth