Поскольку все другие ответы были адекватно предложены, вы можете использовать, __builtin_expect
чтобы дать компилятору подсказку о том, как организовать код сборки. Как отмечают официальные документы , в большинстве случаев встроенный в ваш мозг ассемблер будет не так хорош, как ассемблер, созданный командой GCC. Для оптимизации кода всегда лучше использовать фактические данные профиля, а не гадать.
Аналогичным образом, но еще не упомянутым, существует специфичный для GCC способ заставить компилятор генерировать код по «холодному» пути. Это предполагает использование noinline
и cold
атрибутов, которые делают именно то , что они звучат , как они делают. Эти атрибуты могут применяться только к функциям, но в C ++ 11 вы можете объявлять встроенные лямбда-функции, и эти два атрибута также могут применяться к лямбда-функциям.
Хотя это все еще попадает в общую категорию микрооптимизации, и поэтому применяется стандартный совет - тестируйте, а не угадайте - я считаю, что в целом он более полезен, чем __builtin_expect
. Вряд ли какие-либо поколения процессоров x86 используют подсказки предсказания ветвления ( справочные ), поэтому единственное, на что вы все равно сможете повлиять, - это порядок кода сборки. Поскольку вы знаете, что такое код обработки ошибок или «пограничный» код, вы можете использовать эту аннотацию, чтобы гарантировать, что компилятор никогда не предскажет ответвление для него и свяжет его с «горячим» кодом при оптимизации по размеру.
Пример использования:
void FooTheBar(void* pFoo)
{
if (pFoo == nullptr)
{
// Oh no! A null pointer is an error, but maybe this is a public-facing
// function, so we have to be prepared for anything. Yet, we don't want
// the error-handling code to fill up the instruction cache, so we will
// force it out-of-line and onto a "cold" path.
[&]() __attribute__((noinline,cold)) {
HandleError(...);
}();
}
// Do normal stuff
⋮
}
Более того, GCC автоматически проигнорирует это в пользу обратной связи профиля, когда она доступна (например, при компиляции с -fprofile-use
).
См. Официальную документацию здесь: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes