Семантика горячего атрибута GCC

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

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

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

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

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

Ответ 1

Официальная документация:

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

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

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

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

2007:

 __attribute__((hot))   

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

Гилад Бен-Йоссеф:

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

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

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

Хорошие кандидаты на горячий атрибут - это основные функции, которые часто называют в вашей базе кода. Хорошими кандидатами для атрибута 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 вернет true для функции (= = "... частота FREQ считается горячей." ). Это превращает значение maybe_hot_bb_p в true для всех базовых блоков (BB) в функции ( "BB может быть интенсивным с CPU и должен быть оптимизирован для максимальная производительность." ) и maybe_hot_edge_p true для всех ребер в функции. В свою очередь, в не-t212 > -модулях эти BB и ребра, а также петли будут оптимизированы для скорости, а не для размера.

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