http://soltysiak.com
..Królowa Kinga została swięta bo Bolesław był wstydliwy..
Tekst pochodzi z tłumaczenia książki Roberta Love - Linux Kernel Programming Guide:
"Kompilator gcc udostępnia dyrektywę optymalizującą wykonanie gałęzi kodu, ktorych
wykonanie jest albo wielce, albo bardzo mało prawdopodobne. Kompilator wykorzystuje tę
dyrektywę do odpowiedniej optymalizacji gąłęzi warunkowej. W kodzie jądra dyrektywa ta jest
obecna pod postacią wygodnych w użyciu makrodefinicji likely() i unlikely().
Na przykład rozważmy następującą instrukcję warunkową:
if (foo) {
/* ... */
}
Aby oznaczyć gałąż kodu jako taką, której wykonanie jest mało prawdopodobne, należy wykorzystać
makrodefinicję unlikely():
if (unlikely(foo)) {
/* ... */
}
a gałęzie, których wykonanie jest niemal pewne, makrodefinicją likely():
if (likely(foo)) {
/* ... */
}
Dyrektywy optymalizujące gałęzie należy wykorzystywać jedynie w przypadkach,
kiedy wybór jednego z wariantów kodu jest w wiekszości przypadków znany z góry
albo kiedy zachodzi potrzeba optymalizacji wykonania jednego z przypadków kosztem
przypadków pozostałych. To bardzo ważne - dyrektywy optymalizujące powodują
zwiększenie wydajności jedynie w przypadku prawidłowego przewidzenia dużej częstotliwości
wykonywania danej gałęzi warunkowej - w przypadkach wyjątkowych zaburzających przewidywanie,
wykonanie kodu gałęzi jest opóźniane."
Oto definicje tych makrodefinicji:
#define unlikely(x) __builtin_expect(!!(x), 1) #define likely(x) __builtin_expect(!!(x), 0)Na marginesie zauważ, że wyrażenie !!(x) nie jest tożsame z (x).
a = 5; b = !a; /* b = 0 */ b = !!a; /* b = 1 */Wyrażenie podwójnej negacji jest filtrem. Dla wartości 0 zwraca 0, dla reszty 1.