Érdekes állat egyébként az AVX512, meg a SIMD úgy általában: egy sikeres karriert végig lehet programozni úgy, hogy nem kell használni soha. És mondják a hozzá nem értők, hogy a compiler így meg úgy rájön és magától használja helyetted, de szerintem egyáltalán nem triviális a probléma, és többnyire a compiler nem fog SIMD optimalizációkat találni, hacsak nem direkt úgy írjuk meg a programot, hogy esélye legyen.
Viszonylag sokat foglalkozok teljesítmény optimalizálással, fogalmazhatok úgy, hogy amit programozok azt mindig végiggondolom teljesítmény szempontból is, és próbálom nem pesszimizálni a kódot. Illetve bizonyos kritikus részeket optimalizálok is. Előfizettem Casey Muratori Performance Aware Programming sorozatára is, és egész sokat feldolgoztam az anyagból: https://www.computerenhance.com/p/welcome-to-the-performance-aware
A konklúzióm az, hogy a legtöbb dolog esetén ha az performance aware tervezés nélkül készül, akkor a RAM sávszélesség (cache miss) és a túl sok kontextusváltás (főleg userspace-kernel váltás) a legfontosabb szűk keresztmetszetek. Ezeken már egy jó tízszeres szorzót is lehet fogni átlagban, de szélsőséges esetben még annál is többet is.
A következő a magas szintű nyelvek virtualizált függvényhívásai, nem inline-olhatóság, illetve a prediktálhatóság elrontása. Ebben az a rossz, hogy ha egyszer úgy kezdtük el, mondjuk Javában amit C-ben kellett volna, akkor utólag nem lehet sokat tenni. Ugyanúgy a cache kihasználtságot is rontják ezek, redesign nélül nem orvosolható módon.
A fent linkelt sorozat sokat foglalkozik az utasítások párhuzamosításával, branch predictionnel, illetve branchless technikákkal. Ezek szintén jelentősek, viszont a legtöbb program nagyon messze van attól, hogy ezekre egyáltalán szükség lehessen. Annak ugyanis előfeltétele volna, hogy az adatok sorban jöjjenek és blokkokban feldolgozhatóak legyenek, hogy ezek a kérdések egyáltalán felmerülhessenek. Márpedig ha a program nem direkt úgy volt tervezve, akkor az objektumok a RAM-ból összevissza jönnek, ugrándozni kell a címek alapján, iterátorokat kell használni a lépkedéshez, és az utasítás pipeline optimális használata esélytelen.
Mindezek után jönne a SIMD használata. Eleve a legtöbb szükséges algoritmus nem alkalmas rá, és a legtöbb megvalósításnak van nagyobb baja is, minthogy ez kellene. Nekem például most nemrég volt az első eset, hogy explicit írtam egy SIMD-t használó programot úgy, hogy 34 éve programozok és ebből kb 20 évet pénzér diplomával. Itt van a sor, két kép framebuffer különbségét számolom ki bájtonként: https://github.com/qgears/rrfb/blob/main/c/src/x11.c#L160 itt például mérhetően jelentős különbség volt a naív megvalósításhoz képest. A fordító nem csinált egyébként SIMD-t magától a naív ciklusból. Lehet, hogy be kellett volna állítani hozzá valami parancssori kapcsolót, nem tudom, mert így működik és örülök és ennyi.
Persze amihez kell, annál nagyon sokat számítanak ezek a SIMD utasítások, többszörös sebességet lehet elérni velük. Szerintem egy alap GUI is használja amikor szoftveres kompozitolás kell, vagy a videó kodekek is szerintem használják. De a legtöbb program explicit semmit nem használ belőlük.
A RAM sávszélesség miatt szkeptikus vagyok a rengeteg core-ral szemben: futtatok teszteket egy 8 magos AMD-n 16 szálon, és mérhetően lassabb a futásidő, ha több teszt fut egyszerre. Mennél több a teszt, annál lassabb minden. Csak a RAM az, amin osztozniuk kell, diszk használat nincs. Hogy fog 128 core osztozni a memória buszon? Tudom, hogy szerverekben már most is vannak ilyenek, úgyhogy biztos van rá mód, de hiszem ha látom. Egyelőre nem dolgoztam ilyenen, úgyhogy szkeptikus vagyok :-)