Opět si připomeňme:
Podpora efektivní optimalizace pro nesymetrické procesory Alder Lake byla přidána až v GCC12 a nenašel jsem zmínku, že by to backportovali do GCC 11.2. E-jádra mají společnou L2 cache pro více jader (a jinak velkou), jinak velkou L1 cache, neumí AVX512 (pravda, P-jádra ho mají taky vypnuté). Takže výkon na jednom typu jader bude na GCC 11.2 vždy trochu trpět.
Zde srovnání z Phoronixu GCC 11.2 a GCC12 s -O3 -march=native. Mimochodem stejný odkaz jsem už dával pod pár týdnů starý článek od p. Ježka ohledně -O3 pro kernel. Jaký je rozdíl mezi verzemi bez march=native, jsem nenašel.
Jenom co jsem tím chtěl říct - berte testy na nesymetrických architekturách trochu s rezervou. Zatím to není ještě úplně doladěná oblast pro běžné použití, takže se v kompilátorech ještě řeší, jak se s tím popasovat.
Osobně by mě zajímalo, jestli se kompilují všechny funkce a kód 2x pro oba typy jader a nějak se za běhu rozhoduje, jaký kód má běžet na kterém jádru nebo jak to ty optimalizace dělá...
Ten patch jen doplňuje ceny různých instrukcí, operací, konstrukcí na nové generaci, aby se optimalizační heuristika líp trefovala. IIRC ten problém byl, že GCC 11 to kompiloval pro ta silnější Golden Cove P-jádra, která mají mimo jiné silně out-of-order execution (512 instrukcí), takže kompilátor nedělá instruction scheduling, nebo aspoň ne tak agresivně, protože počítá s tím, že to udělá procesor. Jenže ty Gracemont E-jádra mají reorder buffer jenom 256 instrukcí dlouhý, takže to u větších celků (funkcí, těl smyček) žerou v naivním pořadí, pipeline se občas zastaví (stall), protože se zbytečně čeká na věci.
Dělat to jak píšete by znamenalo překopání jak vůbec ELF binárky fungují. Každá funkce by musela mít wrapper, který by skočil do jedné nebo druhé varianty podle toho, na jakém jádře to zrovna sedí. A nebo by se při každé migraci procesu z jádra na jádro musela patchnout nějaká vtable, přes kterou by všechna volání funkcí musela jít (což není zadarmo). A nějak by se muselo zabránit migraci, když to zrovna v nějaké optimalizované funkci je. Dneska to ty plánovače přehazují z jádra na jádro i podle teploty, proces se tam doslova ani neohřeje a už ho pakuje :-)
Ono to může být i tím, že nějaká zajímavá instrukce je třeba na tom úsporném jádrě o hodně pomalejší - to, že CPUID říká, že nějaké rozšíření jsou k dispozici ještě úplně neznamená, že je tak výhodné je použít. Ryzeny třeba taky mají PDEP/PEXT (BMI2), ale jsou v mikrokódu a místo 2 cyklů (Intel) trvají 14.