Jakie są prawdopodobne i mało prawdopodobne wywołania w jądrze. Podczas przeszukiwania źródła jądra znalazłem te instrukcje.
# define likely(x) __builtin_expect(!!(x), 1)
# define unlikely(x) __builtin_expect(!!(x), 0)
Czy ktoś mógłby rzucić na to trochę światła?
Odpowiedzi:
Są to wskazówki kompilatora dla GCC. Są one używane w warunkach warunkowych do informowania kompilatora, czy gałąź może zostać podjęta, czy nie. Może pomóc kompilatorowi w ustawieniu kodu w sposób optymalny dla najczęstszych rezultatów.
Są one używane w następujący sposób:
Należy go używać z dużą ostrożnością (tj. W oparciu o rzeczywiste wyniki profilowania gałęzi). Niewłaściwa wskazówka może obniżyć wydajność (oczywiście).
Niektóre przykłady optymalizacji kodu można łatwo znaleźć, wyszukując
GCC __builtin_expect
. Ten post na blogu : optymalizacja gcc: __builtin_expect, na przykład, szczegółowo opisuje demontaż z nim.Optymalizacje, które można wykonać, są bardzo specyficzne dla procesora. Ogólna idea polega na tym, że często procesory będą uruchamiały kod szybciej, jeśli nie rozgałęzią się / nie przeskoczą całego miejsca. Im bardziej jest liniowy i im bardziej przewidywalne są gałęzie, tym szybciej będzie działać. (Dotyczy to zwłaszcza procesorów z głębokimi rurociągami).
Tak więc kompilator wyśle kod w taki sposób, że najbardziej prawdopodobna gałąź nie będzie wymagała przeskoku, jeśli na przykład woli to docelowy procesor.
źródło
Dekompilujmy, aby zobaczyć, co robi z nim GCC 4.8
Bez oczekiwania
Kompiluj i dekompiluj za pomocą GCC 4.8.2 x86_64 Linux:
Wynik:
Kolejność instrukcji w pamięci nie uległa zmianie: najpierw
printf
a potemputs
iretq
powrót.Z oczekiwaniem
Teraz zamień na
if (i)
:i otrzymujemy:
printf
(Skompilowany__printf_chk
) przeniesiono do końca funkcji poputs
i powrotu w celu poprawy przewidywania rozgałęzienia, jak wspomniano w innych odpowiedzi.Jest to w zasadzie to samo co:
Ta optymalizacja nie została wykonana
-O0
.Ale powodzenia w pisaniu przykładu, który działa szybciej
__builtin_expect
niż bez niego, procesory są naprawdę inteligentne . Moje naiwne próby są tutaj .C ++ 20
[[likely]]
i[[unlikely]]
C ++ 20 ustandaryzował te wbudowane C ++: /programming/51797959/how-to-use-c20s-likely-unlikely-attribute-in-if-else-statement Prawdopodobnie ( kalambur!) zrób to samo.
źródło