2013-02-22 6 views
10

Предположим, у меня есть блок компиляции, состоящий из трех функций: A, B и C. A вызывается один раз из функции, внешней по отношению к модулю компиляции (например, это точка входа или обратный вызов); B вызывается много раз A (например, он вызывается в замкнутом цикле); C вызывается один раз при каждом вызове B (например, это библиотечная функция).Семантика горячего атрибута GCC

Весь путь через A (проходящий через B и C) критичен с точки зрения производительности, хотя производительность самого A не является критичной (поскольку большинство времени проводится в B и C).

Каков минимальный набор функций, который следует комментировать с помощью __attribute__ ((hot)), чтобы добиться более агрессивной оптимизации этого пути? Предположим, что мы не можем использовать -fprofile-generate.

Эквивалентно: означает ли __attribute__ ((hot)) «оптимизировать тело этой функции», «оптимизировать вызовы для этой функции», «оптимизировать все вызовы потомков, которые выполняет эта функция», или их комбинация?

На странице информации GCC четко не рассматриваются эти вопросы.

+0

'__attribute__ ((горячий))' может получить вас что-то, но вы можете получить лучшие результаты от первого создания как B, так и C 'static inline' и оптимизации с помощью' -O3'. – twalberg

+0

Я предполагаю, что эти шаги уже сделаны. –

ответ

13

Official documentation:

hot Горячий атрибут функции используется для информирования компилятора, что функция является горячей точкой скомпилированной программы. Функция оптимизирована более агрессивно, и по многим объектам она помещается в специальный подраздел текстового раздела, поэтому все горячие функции оказываются близко друг к другу, улучшая локальность. Когда доступна обратная связь с профилем, через -fprofile-use горячие функции автоматически обнаруживаются, и этот атрибут игнорируется.

Горячий атрибут функций не реализован в версиях GCC ранее 4.3.

Атрибут hot на метке используется для информирования компилятора о том, что путь, следующий за меткой, более вероятен, чем пути, которые не так аннотируются. Этот атрибут используется в случаях, когда __builtin_expect не может использоваться, например, с вычисленным goto или asm goto.

Горячий атрибут на этикетках не реализован в версиях GCC раньше 4.8.

2007:

__attribute__((hot)) 

Подсказка, что отмеченная функция «горячая» и должна быть оптимизирована более агрессивно и/или помещена рядом других «горячих» функций (кэш местности).

Gilad Ben-Yossef:

Как следует из их названия, эти функциональные атрибуты используются для намекают компилятор, что соответствующие функции называются часто в коде (горячей) или редко называется (холодной).

Затем компилятор может запросить код в ветвях, таких как инструкции if, в пользу ветвей, которые называют эти горячие функции и функции функций холода холода, в предположении, что более вероятно, что отрасль, которая будет принята, будет вызовите горячую функцию и с меньшей вероятностью вызовите холодную.

Кроме того, компилятор может группировать функции, помеченные как горячие, в специальном разделе в сгенерированном двоичном формате, исходя из предпосылки, что поскольку кеши данных и команд работают в зависимости от локальности или относительного расстояния от связанного кода и данных , добавление всей часто называемой функции вместе приведет к лучшему кэшированию их кода для всего приложения.

Хорошие кандидаты на горячий атрибут - это основные функции, которые часто называют в вашей базе кода. Хорошими кандидатами для атрибута cold являются внутренние функции обработки ошибок, которые вызываются только в случае ошибок.

Так, согласно этим источникам, __attribute__ ((hot)) означает:

  • оптимизирует вызовы этой функции
  • оптимизировать тело этой функции
  • положить тело этой функции .hot секции (в группу все горячие коды в одном месте)

После анализа исходного кода можно сказать, что "горячие" атрибут проверяется с помощью (lookup_attribute ("hot", DECL_ATTRIBUTES (current_function_decl)); и когда это правда, для функций node->frequency установлено значение NODE_FREQUENCY_HOT (predict.c, compute_function_frequency()).

Если функция имеет частоту, NODE_FREQUENCY_HOT,

  • Если нет информации профиля и нет likely/unlikely на ветвях, maybe_hot_frequency_p возвращает истину для функции (==»... Частота FREQ считается быть горячим. "). Это превращает значение maybe_hot_bb_p в значение true для всех базовых блоков (BB) в функции («BB может быть интенсивным с процессором и должен быть оптимизирован для максимальной производительности») и maybe_hot_edge_p true для всех функций в ребрах. В свою очередь, в не--Os-моделях эти BB и ребра, а также петли будут оптимизированы для скорости, а не для размера.

  • Для всех исходящих вызовов от этой функции, cgraph_maybe_hot_edge_p вернет true ("Вернуть true, если вызов может быть горячим."). Этот флаг используется в ИПС (ИПС-inline.c, ипа-cp.c, ипа-рядный analysis.c) и влияние встроенных и клонированию решений

+0

Не думайте так. Он неполный, и необходимы некоторые эксперименты. Я думаю, что горячий может также повлиять на код, вызванный из горячей функции. – osgx

+1

вы можете ожидать, что gcc теперь или в будущем будет распространять горячность функции на ее дочерние и дочерние ветви и функции, которые они вызывают, где gcc может определять граф вызовов. – codeshot

+0

@codeshot Если это делается вслепую ко всем предкам и потомкам, то большую часть времени вся программа будет отмечена как горячая, нет? Также в сценарии, когда функция имеет несколько предков, и часто используется только одна, это будет пустой тратой. – Jeevaka