programmatūra · 6 min · 23.08.2026

GCC ielāps maina divas rindas Zen 5 izmaksu tabulā: 544.nab_r iet par 12 % ātrāk

Venkataramanans Kumars no AMD 22. augustā nosūtīja GCC izstrādātāju sarakstam ielāpu, kas maina divus skaitļus kompilatora izmaksu tabulā. Viens fails, divas rindas iekšā, divas ārā. Uz Zen 5 procesora SPEC CPU testa 544.nab_r rezultāts pēc tam uzlabojas par 12 %, uz Zen 4 par 9 %. Kompilēts ar -O3 -march=native -flto, vienā kopijā.

Mainītais lielums saucas branch mispredict scale. GCC to glabā katram atbalstītajam procesoram atsevišķā struktūrā failā gcc/config/i386/x86-tune-costs.h. Tabulās znver4_cost un znver5_cost tur līdz šim stāvēja COSTS_N_INSNS (2), ielāps to pārraksta uz COSTS_N_INSNS (2) + 3. Makross COSTS_N_INSNS reizina argumentu ar četri, tāpēc skaitlis aug no 8 uz 11.

ko šis skaitlis nosaka

GCC ir RTL caurlaide ar nosaukumu if-conversion. Tā meklē īsus if zarus un mēģina tos izpildīt bez lēciena: aprēķina abus variantus, tad ar cmov paņem vajadzīgo. Kods iznāk garāks, bet procesors netērē laiku uz nepareizi uzminētu zaru. Vai maiņa atmaksājas, izlemj mērķa arhitektūras izmaksu modelis.

x86 aizmugurgalā to dara funkcija ix86_max_noce_ifcvt_seq_cost failā i386.cc. Tā reizina BRANCH_COST ar tabulas lauku br_mispredict_scale un atgriež reizinājumu kā budžetu, ko caurlaide drīkst iztērēt bezlēcienu variantam. Kad skaitlis aug no 8 uz 11, budžets aug par 37,5 %. Pārbaudi tad izturē arī garākas cmov virknes, kuras iepriekš tika atmestas kā pārāk dārgas.

Funkcijas komentārs paskaidro, kāpēc lauks vispār pastāv:

For modern machines with deeper pipeline, the penalty for branch misprediction could be higher than before to reset the pipeline slots.

Tests, kas uzlabojas, ir 544.nab_r no SPEC CPU 2017 peldošā punkta komplekta. Tas rēķina molekulāro dinamiku ar Nucleic Acid Builder kodu: nolasa atomu koordinātas PDB formāta failā, tad simulē to mijiedarbību pēc norādītā spēka lauka. Iekšējie cikli ir īsi un pilni ar nosacījumiem, kuru rezultātu zaru prognozētājs neuzmin.

trīs tabulas no 34

Failā x86-tune-costs.h šobrīd ir 34 rindas ar branch mispredict scale. Paceltā vērtība 23. augustā stāv tikai trijās: icelake_cost, alderlake_cost un generic_cost. Zen tabulas vēl gaida. Abas mainās vienā ielāpā tāpēc, ka znver5_cost pagaidām ir znver4_cost kopija, ko failā atzīmē atsevišķs komentārs.

Generic tabula savu pluss trīs saņēma jūnijā. Ielāpu 15. maijā iesūtīja Lili Cui no Intel ar tādu pašu argumentu par dziļākiem konveijeriem. No GCC x86 uzturētāju puses Hongtao Liu uzreiz pavaicāja, ko par to domā AMD.

Atšķirība starp jūnija un augusta ielāpu ir tā, kura tabula tiek lasīta. Ja lietotājs kompilē ar -march=native uz Zen 5 mašīnas vai tieši norāda -mtune=znver5, GCC ņem znver5_cost tabulu un generic vērtību neredz nemaz. Jūnija uzlabojums tādā gadījumā pagāja secen. Praksē tas dala lietotājus divās daļās. Debian, Fedora un pārējie izplatījumi savas pakotnes būvē ar -mtune=generic, tāpēc jūnija izmaiņa viņu binārfailos jau ir. Tie, kas dzen -march=native uz savas mašīnas, to nesaņēma.

30 % zaudējums Hint testā

Atbildot uz jūnija jautājumu, AMD komanda nopublicēja mērījumus uz Zen 5: SPEC2017, SPEC2026 un daļa Phoronix testu. 544.nab_r kļuva par apmēram 10 līdz 12 % ātrāks, pārējie SPEC testi palika vietā, Phoronix komplektā neitrāli bija visi izņemot vienu. Hint tests ar iestatījumiem -O2 -march=generic -mtune=znver5 palēninājās par apmēram 30 %. Tas pats notika ar -mtune=graniterapids.

AMD tomēr izmaiņu atbalstīja un ierosināja Hint gadījumu risināt atsevišķi. Cui ielāpu ieviesa 24. jūnijā un reģistrēja Bugzilla pieteikumu 125970, kas šo blakusefektu izseko. Phoronix pēc tam nomērīja generic izmaiņu plašāk: 544.nab_r rezultāts uzlabojās par 12,7 % uz Intel Granite Rapids un par 12,1 % uz Zen 5.

Viena rinda tabulā tātad dod divciparu ieguvumu vienam testam un divciparu zaudējumu citam. Izmaksu modelis apraksta, cik dārga ir nepareiza prognoze vidēji. Konkrētam ciklam vidējais var būt tālu no patiesības. Hint gadījumā zari ir labi paredzami, tāpēc lēciens tur izmaksā mazāk par bezlēcienu aritmētiku, ko kompilators tagad izvēlas biežāk.

kā to pamērīt bez ielāpa

Funkcija ix86_max_noce_ifcvt_seq_cost vispirms pārbauda, vai lietotājs pats ir norādījis parametrus max-rtl-if-conversion-predictable-cost vai max-rtl-if-conversion-unpredictable-cost. Ja kāds no tiem ir uzstādīts komandrindā, funkcija atgriež to vērtību un tabulu neaiztiek. Sekas praktiskas: budžetu var pacelt jau ar esošu GCC 16, pievienojot --param max-rtl-if-conversion-unpredictable-cost=N. Kompilatoru pārbūvēt nevajag.

Tas ir arī veids, kā pārbaudīt, vai izmaiņa palīdz konkrētam projektam. Divciparu skaitļi šeit nāk no viena SPEC testa, kas rēķina fiziku ciešā ciklā. Tipiskā serveru kodā ar daudz atmiņas piekļuvēm un sistēmas izsaukumiem no if-conversion budžeta paplašināšanas neizriet nekas.

Ielāps ir nokārtojis bootstrap un regresijas testus uz x86_64-linux. Vēstulē Kumars prasa uzturētāju atļauju. Phoronix gaida to GCC 17 laidienā ar iespējamu atgriešanu GCC 16.3 sērijā. GCC master koda kokā 23. augustā znver4_cost un znver5_cost rindās joprojām stāv COSTS_N_INSNS (2).

Avoti

komentārisaruna

Komentāri

Šim rakstam vēl nav komentāru. Esi pirmais, kurš dalās ar savu viedokli.

Pievieno komentāru

Tavs e-pasts netiks publicēts. Obligātie lauki atzīmēti.

vēl no programmatūrasaistītie