Tak důvod proč první SSE a pak SSE2 je aby Intel prodal nové CPU co toho umí víc - stejně tak rozdíl v AVX a AVX2 (tam šel Intel jak přes kopírák a přitom AVX nebylo vůbec potřeba, stačilo rovnou AVX2, tak jak potom šel Intel cestou AVX-512)
Překladače umí SSE2 dobře, ale problém je ten, že SSE2 je snad nejmíň vybalancovaná SIMD ISA co existuje, takže překladače potřebujou většinou SSE4.1 a nebo nejlépe AVX2/AVX-512 aby byly schopné vůbec něco autovektorizovat.
Ono by bylo hezké to srovnat s NEON, který až na shuffling a pár specialit je podobný SSE4.1 a má i hezké bonusy (třeba rozsáhlé widening / narrowing operace).
SYN+ACK
https://github.com/fraunhoferhhi/vvenc/issues/127
A to som len naflákal pár prepínačov len tak avec plaisir.
Myslím to tak, že Intel navrhnul AVX-512, investoval do marketingu a do vývojářů, aby se tato technologie dostala do klíčových oblastí, a pak si řekne, že AVX-512 nebude v consumer segmentu. Mezi tím vyrobí AMD celý line-up procesorů s výbornou implementací AVX-512 (Zen 4) a pak tomu nasadí korunu v podobě Zen 5, což je něco o čem se v Intelu ani nesní (ten výkon je tak enormní, že se dá hodně těžko saturovat).
Primární cíl SSE byla 3D grafika (hry) a tam float plně postačovaly a SSE rozhodně pomohlo. Skalární součin vektorů na jednu instrukci, násobení vektoru maticí na 4 + 3 instrukce (nebo jen 4 s FMA, které bylo až později), násobení matic na 16 + 12 instrukcí. U AVX-512 pak všechno za čtvrtinu.
Neon umí pro změnu multiply by lane - násobení vektoru vybraným prvkem z vektoru, které je pro násobení matic ještě lepší než shuffling.
Autovektorizace viz https://github.com/kvr000/zbynek-cxx-exp/tree/master/simd/matrix-multiplication - compiler "ref" je na stejné úrovni jako SSE. Ale některá měření jsou dost stará, chtělo by to vyzkoušet s novějšími kompilátoru a taky Gcc vs Clang (Gcc v tomhle bylo dlouho lepší, ale dnes to může být jinak).
Já bych tam nehledal konspirace, ty SSE chtěli zákazníci (nepřímo): původní MMX a hlavně 3D Now byly značně omezené, nejen velikostí, ale hlavně konfliktem s FPU. Ono původní x87 FPU bylo peklo samo o sobě. Takže první krok bylo SSE s cílem nahradit FPU a mít SIMD na float operace. V dalších defakto nahradili i MMX.
Další evoluce řeší jiné úlohy třeba v oblasti kryptografie, další optimalizace (FMA), atd, a hlavně růst. Intel nemohl uvést 512-bitové SIMD s 32 registry před 25 lety, když s ním má problém ještě dnes - v té době by AVX-512 snad znamenalo sálový počítač (trochu přeháním :-D ).
Podobnou evoluci má ARM - SIMD extension, Neon, SVE, SVE2. Risc-V jako relativní novinka je na tom líp - jestli jde správným směrem se ukáže později.
Intel ani nebyl první se SIMD - MIPS, Pa-Risc, Sparc je mělo dřív, pominu-li 1970s supercomputers.
Když vezmu AArch64, tak NEON je vcelku kompletní a hlavně je tam balanc (stejné operace pro různé datové typy), kdežto Intel to lepil jak mohl a ta cesta byla hodně dlouhá (SSE2, SSE3, SSSE3, SSE4.1, SSE4.2).
Třeba zaokrouhlování (ne SIMD, i scalar) bylo implementované až v SSE4.1 - tak dlouho musel člověk čekat aby měl obyčejný round-to-even nebo floor/ceil i pro skalární float/double a nemusel jít přes FPU nebo volat nějakou libc funkci, která to nějak implementovala, většinou bez FPU...
Porovnání integerů nebo třeba tak základní operace jako je MIN/MAX různých datových typů, to se opět objevilo až v SSE4.1, porovnání 64-bit integeru až v SSE4.2!
Za mě celkem bordel a nepochopitelné omezení v původním návrhu SSE2 ISA, které je s náma dodnes (protože když člověk nespecifikuje rozšíření při kompilaci, tak většinou dostane ten kód co využívá max. SSE2, protože SSE2 je baseline pro X86_64 ISA).
BTW nikdy jsem nepsal, že mělo být rovnou AVX-512. Jen jsem psal, že SSE/SSE2 mělo být rovnou SSE2, a AVX/AVX2 mělo být rovnou AVX2, protože jinak to vůbec nedává smysl. Toho kódu jen pro SSE zase tolik nebylo (umělo to jen float, což není moc použitelné), a pro AVX platí to samé - není všechno jen float, člověk potřebuje i jiné operace pro většinu kódu. Výsledek je takový, že kódu co využívá AVX bez AVX2 moc není, protože to je opruz psát a spravovat, když můžu rovnou použít AVX2.
dneska už málokdo. Ale třeba intrinsic v GCC, které vlastně přímo generují ty instrukce, mají podtržítka a to už jde číst docela dobře (až na ten prefix _mm):
__m128 shuf = _mm_shuffle_ps(r1, r1, _MM_SHUFFLE(2, 3, 0, 1));
__m128 sums = _mm_add_ps(r1, shuf);
shuf = _mm_movehl_ps(shuf, sums);
sums = _mm_add_ss(sums, shuf);
float result = _mm_cvtss_f32(sums);
pár z těch instrukcí skončilo i tady na top listu https://www.youtube.com/watch?v=Wz_xJPN7lAY
(vlastne skoro vsechny jsou nejaky SIMD :)
13. 3. 2025, 19:00 editováno autorem komentáře
Díky. Ta tabulka může být opravdu zajímavá a užitečná, takže díky za odkaz. Ale popravdě teď jen podpořila mé přesvědčení, že by se tím dalo strašit: "Ještě jeden bug dneska vyrobíš v tom Javascriptu a převelím tě do oddělení jazyka s těmito klíčovými slovy!" - a prásk nejnovějším výtiském této tabulky o stůl. Stačí fontem devítkou, už tak to bude štos :)
Nevěřím! :-)
Lépe řečeno chápu ten pocit, na osmibitovém atárku jsem ho měl taky :) Jenže to mělo pár desítek instrukcí a když mělo další procesory s vlastní instrukční sadou, tak to bylo jasně oddělené a tím přehlednější. Ale takhle spojené všechno do jedné tabulky musí podle mě fakt strašit - umět účelně využít všechny tyto instrukce nebo aspoň koncepty a ještě zoptimalizovat libovolný netriviální program, to podle mě nejde bez pomoci stroje. A možná ani s ním ne :)
Pochopitelnější mi to přijde právě v tomto vašem seriálu, protože jak je to v jednotlivých kapitolách, tak je jasné, co je k čemu a, když píšu program, tak která kapitola mě zajímá a kterými se teď nemusím zabývat - podle toho, co zrovna v této části programu budu řešit.
Vždyť ten AsmGrid tam má regex filtr - stačí tam napsat SSE2 a máte všechny SSE2 instrukce hezky pohromadě. Nebo ZMM a máte všechny AVX-512 instrukce co používají ZMM registry, atd... Pro mě zatím neocenitelný nástroj, protože píšu i raw asm a tady mám všechno pohromadě, a stačí přepnout tab a mám i latence, atd...
Jako jo, dovedl bych si představit i něco lepšího, ale dělat bych to nechtěl :)
Zkusím to doplnit. Nemyslel jsem to tak, že bych v každé situaci preferoval x86 assembler (ale vlastně ani žádný starší RISC) oproti vyšším jazykům (Intel to podle mě neudělal dobře od začátku, ale zrovna SIMD to vylepšil).
Ovšem kdybych stál před volbou: práce v asm vs. práce v JS, tak bych šel do asm. Zaprvé vím, jak to funguje a mám s tím (vlastně jen díky věku :-) nějaké zkušenosti a zadruhé se JS světu snažím vyhýbat, co to jde (asi úchylka, ale ve světě, kde se masivně mění technologie každou chvíli, je asm či C taková rozumná stálice).
Používám AVX-512F pro integer operace v kryptografii a zarazila mě neexistence operace "unární bitové not" případně "binární bitové not". Zapsal jsem to do C kompilátoru a následně opsal výsledné instrukce. Pro "bitové not" tedy teď používám kombinaci dvou operací: "load 0xFF from 8bit register to 512bit register and expand" a hned po ní instrukci "bitové XOR". Nějaký důvod proč taková instrukce v AVX-512F není?