Skrivet av klk:
Eftersom det går att kopiera en hel rad eller flera rader som ett block är det lätt att få till SIMD. SIMD är framförallt viktigt vid större mängder data. Ta att dela upp arbete i trådar. 10 trådar där varje tråd kör sin tårtbit och när de är klara så skall data snabbt samlas i en huvudtabell
???
SIMD -> parallellism på en enskild kärna. Normalt av typen data-parallelism p.g.a. av "S" i SIMD.
MIMD -> dela upp arbetet i flera trådar. Stödjer både data-parallelism men också uppgifts-parallelism.
Med MIMD kan det vara prestandamässigt negativt att packa data allt för mycket, kan ge "false-sharing" vilket kan vara en rejäl prestandadödare (i sina värsta former går det då långsammare ju fler kärnor man slänger på problemet).
Så kör du SIMD eller MIMD?
Skrivet av klk:
Idag gissar jag, förr tittade jag ofta på assembler och kunde också använda profiler men kompilatorer idag är löjligt duktiga på att optimera kod med rätt flaggor. Och det skiljer också så mycket beroende på vad man ställer in så det tar mycket tid och granska.
Vet på ett ungefär vad kompilatorn klarar att optimera
Skulle inte kompilatorn klara av att kompilera bästa koden idag så vet man ibland på ett ungefär vad den kommer klara av snart
Exempelvis så äldre C++ bibliotek, den kunde ha assembler för att räkna längd på sträng, eller assembler för memcpy. Idag tror jag de flesta låter kompilatorn generera upp bäst kod
Här känns det igen mer som "vet på ett ungefär vad en kompilator från förra årtusendet klarar att optimera".
Just strängoperationer är något som rätt ofta är handoptimerade m.h.a. SIMD idag. Detta då egentligen inget av de "normala" språken har något vettig stöd för att uttrycka vad man vill göra som låter en kompilator göra ett bra jobb. Men är inte en omöjlig uppgift, Nvidias CUDA (GPU) och Intels ISPC (SIMD på CPU och GPU) är båda dialekter av C/C++ som har en semantik gör det möjligt för en kompilator att göra väldigt bra SIMD-kod.
Något kompilatorer/länkare är långt bättre på idag är att ta program som är uppdelade i många små (och enkla att testa...) delar, men ändå optimera det som-om allt är skrivet som en big-ball-of-mud.
Och kopplingen mellan "vilken assembler blir det / hur många instruktioner blir det" har allt mindre koppling till "hur snabbt körs detta på en modern CPU" då out-of-order fönstret blivit så gigantiskt. En människa ha extremt svårt att överblicka detta, även kompilatorer har problem då de bara har statiskt information och allt mer av prestandaflaskhalsarna är dynamiska (vilket är orsaken till varför JIT:ad kod (som JVM och .NET använder) idag kan vara snabbare än AOT (vilket C, C++, Rust, Go, m.fl. använder)).
Både C++ och Rust arbetar på ett grundläggande SIMD stöd i deras standardbibliotek. Rust-varianten är hyfsat färdig, men inte i skarp release än (men är alltid med och går att slå på med flaggor). C++ varianten är lite längre från att hamna i standarden, men går att test-köra. Ingen av dessa tar stödet lika långt som CUDA/ISPC, men ändå långt bättre stöd av vad som finns idag.
Skrivet av klk:
Det tar för lång tid för mig att beskriva och eftersom jag inte är i närheten att kunna förklara HN, hur det kan vara bra så kommer den biten definitivt inte gå och beskriva här.
finns mycket trick för att hantera kod
Tror alla som varit med i NH-diskussionen greppar vad NH är. Det jag tror ingen alls fattar är vad i HN du hävdar gör det så mycket enklare att "scanna stora mängder kod".
Och även här måste det ju finnas en eller flera specifika detaljer som gör C++ helt överlägsen allt annat då de överhuvudtaget inte har funktionen. DET måste vara trivialt att exemplifiera. Du har gjort ett par försök, alla har så här lång fallit totalt platt då du inte har koll på vad som faktiskt är möjligt i alternativen.