Семантика 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))   

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

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

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

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

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

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

Итак, согласно этим источникам, __attribute__ ((hot)) средства:

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

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

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

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

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

Другие вопросы по тегам