Оскільки в інших відповідях запропоновано всі відповідні пропозиції, ви можете скористатися, __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