Inżynier z firmy Intel wprowadził jednolinijkową zmianę w zestawie kompilatorów GCC, zwiększającą wagę błędnego przewidywania gałęzi na procesorach x86. Zmiana pozwoliła na zwiększenie wydajności kodu generowanego w teście 544.nab_r o 12,7% przy włączeniu optymalizacji „-O2 -mtune=graniterapids” dla CPU Intel Granite Rapids/Xeon 6 oraz o 12,1% przy włączeniu optymalizacji „-O2 -mtune=znver5” na CPU AMD Zen5.
Zmiana wagi z „COSTS_N_INSNS (2)” na „COSTS_N_INSNS (2) + 3” zwiększa znaczenie błędu przewidywania z 2 do 5 instrukcji warunkowych, co lepiej odzwierciedla charakterystykę potoków przetwarzania instrukcji (pipeline) w nowoczesnych CPU, gdzie błędy przewidywania gałęzi są bardziej kosztowne. Zmiana wagi prowadzi do wymuszenia przekształcenia przez kompilator instrukcji „if” w instrukcje warunkowe bez przeskoków, takie jak CMOV, eliminujące przerwy przy błędnym przewidywaniu gałęzi spowodowane koniecznością resetowania stanu potoku. Wcześniej waga „COSTS_N_INSNS (2) + 3” była wskazywana w GCC tylko dla procesorów Intel Ice Lake i Alder Lake, a teraz została ustawiona dla ogólnego (generic) profilu procesorów x86.
Ciekawe, że po przyjęciu łaty ujawniona została regresja, przez co test „Hint” stał się wykonywany u jednego z deweloperów GCC 30% wolniej przy kompilacji z opcjami „-march=generic -mtune=znver5” i „-march=generic -mtune=graniterapids”. Wydajność przechodzenia testów SPEC2017 i SPEC2026 po wprowadzeniu zmiany pozostała na tym samym poziomie. Obecność regresji została potwierdzona przez autora pierwotnego zatwierdzenia, według jego danych spowolnienie przechodzenia testu Hint wynosi 14% przy kompilacji z opcjami „-O2 -mtune=generic -march=x86-64-v3”.
Spowolnienie tłumaczy się tym, że w kodzie testu Hint znajduje się tylko jedna konstrukcja warunkowa, przekształcana przez GCC do reprezentacji opartej na CMOV. Konstrukcja ta wykonywana jest dość rzadko (w 3%) i jej optymalizacja nie wpływa na wydajność. Zmiana trybu generacji kodu doprowadziła jednak do efektu ubocznego, który spowolnił wykonanie bardziej często wykonywanego kodu.
Źródło: opennet.ru
