Ponieważ wszystkie inne odpowiedzi odpowiednio zasugerowały, możesz użyć, __builtin_expect
aby dać kompilatorowi wskazówkę, jak zorganizować kod asemblera. Jak wskazują oficjalne dokumenty , w większości przypadków asembler wbudowany w twój mózg nie będzie tak dobry, jak ten stworzony przez zespół GCC. Zawsze najlepiej jest używać rzeczywistych danych profilu do optymalizacji kodu, zamiast zgadywać.
W podobny sposób, ale jeszcze nie wspomniano, znajduje się specyficzny dla GCC sposób wymuszenia na kompilatorze generowania kodu na „zimnej” ścieżce. Obejmuje to użycie atrybutów noinline
i cold
, które robią dokładnie to, na co wyglądają. Te atrybuty można zastosować tylko do funkcji, ale w C ++ 11 można deklarować wbudowane funkcje lambda, a te dwa atrybuty można również zastosować do funkcji lambda.
Chociaż nadal należy to do ogólnej kategorii mikrooptymalizacji, a zatem ma zastosowanie standardowa rada - test nie zgaduj - wydaje mi się, że jest ona bardziej użyteczna niż __builtin_expect
. Prawie żadne generacje procesorów x86 nie używają wskazówek dotyczących przewidywania rozgałęzień ( odniesienie ), więc jedyną rzeczą, na którą i tak będziesz mógł wpłynąć, jest kolejność kodu asemblera. Ponieważ wiesz, co to jest kod obsługi błędów lub kod „przypadków skrajnych”, możesz użyć tej adnotacji, aby upewnić się, że kompilator nigdy nie przewidział do niego gałęzi i połączy go z „gorącym” kodem podczas optymalizacji pod kątem rozmiaru.
Przykładowe użycie:
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
⋮
}
Co więcej, GCC automatycznie zignoruje to na korzyść opinii o profilu, gdy jest dostępna (np. Podczas kompilacji -fprofile-use
).
Zobacz oficjalną dokumentację tutaj: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes