Programování v asembleru – FPU a spol. Jakub Yaghob
Ještě jednou historie – FPU Floating Point Unit Formát dat i výpočet odpovídá IEEE 754 Koprocesor Nejprve samostatný čip 8086+8087, 80186+80187, 80286+80287, 80386+80387 Integrovaný na čipu s hlavním procesorem i486, Pentium, Pentium Pro, Pentium II, Pentium III, Pentium IV Výpočet probíhá paralelně s výpočtem hlavního procesoru
Ještě jednou historie – MMX První pokus o SIMD na IA-32 Prvně implementováno v procesorech Pentium MMX a Pentium II Pouze celočíselné operace Vzájemně se vylučuje s FPU Používá registry FPU AMD odpovědělo technologií 3DNow
Ještě jednou historie – SSE Streaming SIMD extensions Implementováno poměrně pozdě Pentium III Vlastní nové registry XMM, MXCSR Operace SIMD ve „float“ přesnosti Instrukce pro řízení cache, prefetch
Ještě jednou historie – SSE2 Pentium IV Používá registry z SSE Operace SIMD v „double“ přesnosti 128-bitové operace SIMD na celých číslech Instrukce pro řízení cache, pořadí paměťových operací
Ještě jednou historie – SSE3 Nová generace procesoru Pentium IV (Prescott) a procesory Core Další rozšíření SSE2 Další SIMD operace „Horizontální“ SIMD operace Monitor
Ještě jednou historie – SSE4 Rozděleno na dvě rozšíření SSE4.1 a SSE4.2 SSE4.1 45nm Core 2 47 nových instrukcí Zlepšení výkonu pro zpracování médií, 3D SSE4.2 Core i7 7 nových instrukcí Zpracování řetězců, aplikační instrukce
Ještě jednou historie – AVX Advanced Vector eXtensions Rozšíření SSE registrů na 256 bitů 3-operandový zápis instrukcí ADDPS xmm1,xmm2/m128 VADDPS xmm1,xmm2,xmm3/m128 Většina instrukcí bez omezení na zarovnání Prefix instrukce VEX
Výpočetní prostředí FPU I.
Výpočetní prostředí FPU II. Datové registry Zásobník Výpočet v obrácené polské notaci
Výpočetní prostředí FPU III. Stavový registr Pouze pro čtení Podmínkové příznaky se chovají u různých instrukcí různě ES nastaveno, kdykoliv nějaké xE nastaveno Při SF rozhoduje C1=1 (overflow), C1=0 (underflow)
Výpočetní prostředí FPU IV. Řídící registr Maska výjimek Řízení přesnosti Ovlivňuje pouze operace +,-,*,/, sqrt Řízení zaokrouhlování 00 24 bitů 01 Vyhrazeno 10 53 bitů 11 64 bitů 00 Nejbližší sudý 01 K −∞ 10 K +∞ 11 K 0
Výpočetní prostředí FPU V. Značkovací registr Vázáno na fyzické registry
Datové typy FPU I. Numerické typy Odpovídají IEEE 754 32- a 64-bitová čísla mají implicitní celou část mantisy = 1 Hodnota = -1Sign * Mantisa * 2Exponent-Posun exponentu
Datové typy FPU II. Celočíselné typy
Datové typy FPU III. Nekonečno Další typy hodnot Numerické Celočíselné = 10...0 Další typy hodnot NaN (Not a Number) Quiet Signaling Nenormalizované číslo
Instrukce FPU – přesuny Float FLD mem FLD ST(i) FST, FSTP mem FST, FSTP ST(i) FXCH ST(i) FCMOVcc ST(0),ST(i) Integer FILD mem FIST, FISTP mem BCD FBLD mem FBSTP mem
Instrukce FPU – konstanty Load +0.0 FLDZ Load +1.0 FLD1 Load π FLDPI Load log2 10 FLDL2T Load log2 e FLDL2E log10 2 FLDLG2 loge 2 FLDLN2
Instrukce FPU – aritmetika Sčítání FADD mem FADD ST(0),ST(i) FADD ST(i),ST(0) FADDP ST(i),ST(0) FIADD mem Odčítání FSUB/FSUBP FSUBR/FSUBRP FISUB/FISUBR Násobení FMUL/FMULP FIMUL Dělení FDIV/FDIVP FDIVR/FDIVRP FIDIV/FIDIVR Ostatní FABS FCHS FSQRT FPREM, FPREM1 FRNDINT FXTRACT
Instrukce FPU – porovnání Float FCOM/FCOMP mem FCOM/FCOMP ST(i) FCOMPP Float neuspořádané FUCOM/FUCOMP FUCOMPP Integer FICOM/FICOMP mem Přímé float FCOMI/FCOMIP Přímé float neuspořádané FUCOMI/FUCOMIP Ostatní FTST FXAM
Instrukce FPU – trigonometrické sin FSIN cos FCOS sin a cos FSINCOS tg FPTAN arctg FPATAN
Instrukce FPU – logaritmické a exponenciální Logaritmus y * log2 x FYL2X Logaritmus y * log2 x+1 FYL2XP1 Exponent 2x-1 F2XM1 Násobení mocninou 2 FSCALE
Instrukce FPU – řídící Inicializace Řídící slovo Stavové slovo Výjimky FINIT/FNINIT Řídící slovo FLDCW FSTCW/FNSTCW Stavové slovo FSTSW/FNSTSW Výjimky FCLEX/FNCLEX Ukazatel zásobníku FINCSTP/FDECSTP Prostředí FLDENV FSTENV/FNSTENV Stav FRSTOR FSAVE/FNSAVE Ostatní FFREE FNOP WAIT/FWAIT
Porovnání ve FPU – I Tradiční metoda
Porovnání ve FPU – II Novější metoda Od Pentia Pro Porovnávací instrukce přímo nastavují odpovídající příznaky v EFLAGS jako bezznaménkové porovnání Instrukce pro porovnání: FCOMI, FCOMIP, FUCOMI, FUCOMIP Instrukce pro podmíněný přesun: FCMOVcc ST(0),ST(i)
Porovnání ve FPU – III Unordered porovnání Nastavení příznaků Aspoň jeden NaN Nastavení příznaků
Hlášení výjimek FPU FPU pracuje paralelně s hlavním proudem instrukcí Kdy se má vyvolat výjímka pro FPU v hlavním proudu? Na další FPU instrukci WAIT/FWAIT Problém s ukládáním dat FPU: kdy je uvidím v hlavním proudu? Od i486 není třeba
Výpočetní prostředí MMX Registry jsou sdíleny s FPU Mantisová část registrů
Datové typy MMX
SIMD model
Modely aritmetiky MMX Wraparound Znaménková saturace „Normální“ aritmetika, která nekontroluje žádné přetečení Znaménková saturace Při přetečení/podtečení přes znaménkové maximum/minimum je výsledkem znaménkové maximum/minimum Bezznaménková saturace Při přetečení/podtečení přes bezznaménkové maximum/minimum je výsledkem bezznaménkové maximum/minimum
Instrukce MMX – datové přesuny 32-bitů MOVD mem,mmxr MOVD mmxr,mem MOVD r,mmxr MOVD mmxr,r 64-bitů MOVQ mem,mmxr MOVQ mmxr,mem MOVQ mmxr,mmxr
Instrukce MMX – aritmetika Sčítání PADDB mmxr,mmxr PADDB mmxr,mem PADDW, PADDD PADDSB, PADDSW PADDUSB, PADDUSW Odčítání PSUBB, PSUBW, PSUBD PSUBSB, PSUBSW PSUBUSB, PSUBUSW Násobení PMULL, PMULH Násobení a sečtení PMADDWD
Instrukce MMX – porovnání a konverze Porovnání na rovnost PCMPEQB PCMPEQW PCMPEQD Porovnání na > PCMPGTB PCMPGTW PCMPGTD Stažení PACKSSWB, PACKSSDW PACKUSWB Rozbalení PUNPCKHBW PUNPCKHWD PUNPCKHDQ PUNPCKLBW PUNPCKLWD PUNPCKLDQ
Instrukce MMX – logické a posuvy, EMMS PAND PANDN POR PXOR Posuvy PSLLW, PSLLD, PSLLQ PSRLW, PSRLD, PSRLQ PSRAW, PSRAD EMMS (Empty MMX state) EMMS
Přechody MMX a FPU Přechod FPU→MMX TOP v SW je 0 Přechod MMX→FPU Libovolná instrukce MMX kromě EMMS FPU nastavení: TOP v SW je 0 Tag registr je celý 0 V exponentech registrů jsou 1 Přechod MMX→FPU Použít instrukci EMMS Míchaný kód (volací konvence!) Při použití MMX ve funkci je nutno uložit/obnovit stav FPU
Výpočetní prostředí SSE 128-bitové datové registry Intel 64 má navíc 8 registrů XMM8-XMM15
Výpočetní prostředí SSE – řídící/stavový registr Stavový i řídící registr MXCSR
Datové typy SSE Čtyři „floaty“
Instrukce SSE – I Pakované a skalární float operace 64-bitové SIMD celočíselné instrukce Instrukce na řízení stavu Řízení cache, prefetch, pořadí paměťových operací
Instrukce SSE – II Pakované a skalární float operace Přesuny dat Aritmetické instrukce Logické instrukce Porovnání Míchání Konverze
Instrukce SSE - přesuny Aligned 16B, unaligned MOVAPS, MOVUPS SP skalár MOVSS Low, high 2 SP MOVLPS, MOVHPS Low-high, high-low 2 SP MOVLHPS, MOVHLPS 4 nejvýznamnější bity SP do 4 bitů obecného registru MOVMSKPS
Instrukce SSE – aritmetické a logické SIMD aritmetické operace ADDPS, SUBPS, MULPS, DIVPS, RCPPS, SQRTPS, RSQRTPS, MAXPS, MINPS Skalární aritmetické operace ADDSS, SUBSS, MULSS, DIVSS, RCPSS, SQRTSS, RSQRTSS, MAXSS, MINSS Logické operace ANDPS, ANDNPS, ORPS, XORPS Porovnání CMPPS, CMPSS, COMISS, UCOMISS
Instrukce SSE – míchání Zamíchání podle masky SHUFPS Proložení UNPCKHPS UNPCKLPS
Instrukce SSE – konverze Konverze 2 DW INT↔ 2 PS CVTPI2PS, CVTPS2PI, CVTTPS2PI Viz obrázek později Konverze 1 DW INT↔ skalár PS CVTSI2SS, CVTSS2SI
Instrukce SSE – rozšíření MMX Přesuny PEXTRW, PINSRW PMOVMSKB PSHUFW Aritmetické PMULHUW Agregační PAVGB, PMAXUB, PMINUB, PMAXSW, PMINSW, PSADBW
Instrukce SSE – netemporální data Některé MM operace zapisují data, která nebudou v nejbližší budoucnosti zapotřebí Je třeba zabránit zanesení cache Data se neukládají do cache Pokud jsou v cache, cache-line označena jako oběť Zápis s WC sémantikou Není zaručeno pořadí zápisu, slučování ve WC bufferech
Instrukce SSE – netemporální přesuny, řízení cache MOVNTQ, MOVNTPS, MASKMOVQ Řízení přednačítání PREFETCHh h je hint T0 – temporální data do všech úrovní Tx – temporální data do úrovně nejvýše x NTA – netemporální data co nejblíže k CPU bez zanesení cache Pořadí paměťových operací SFENCE
Instrukce SSE – stav Práce s MXCSR Stav SSE LDMXCSR mem STMXCSR mem FXSAVE FXRSTOR Zavedeny před SSE v Pentium II jako rychlé uložení/načtení stavu FPU Nejsou součástí SSE Nyní ukládají stav XMM, MXCSR, FPU, MMX
Datové typy SSE2 128-bitové celočíselné typy Dva „double“
Instrukce SSE2 Pakované a skalární double operace Přesuny dat Aritmetické instrukce Logické instrukce Porovnání Míchání Konverze 64-bitové a 128-bitové celočíselné operace 128-bitové rozšíření stávajících SIMD celočíselných operací MMX a SSE Řízení cache a pořadí paměťových instrukcí Flush-to-Zero flag in MXCSR
Instrukce SSE2 – přesuny Obdoba instrukcí pro SSE, ale určené pro Packed Double-precision MOVAPD, MOVUPD MOVSD MOVHPD, MOVLPD MOVMSKPD
Instrukce SSE2 – aritmetické a logické SIMD aritmetické operace ADDPD, SUBPD, MULPD, DIVPD, SQRTPD, MAXPD, MINPD Skalární aritmetické operace ADDSD, SUBSD, MULSD, DIVSD, SQRTSD, MAXSD, MINSD Logické operace ANDPD, ANDNPD, ORPD, XORPD Porovnání CMPPD, CMPSD, COMISD, UCOMISD
Instrukce SSE2 – míchání Zamíchání podle masky SHUFPD Proložení UNPCKHPD UNPCKLPD
Konverze SSE a SSE2
Instrukce SSE2 – operace v celých číslech Přesuny 128 bitů (Double Quadword) MOVDQA, MOVDQU Aritmetické operace Packed Quadword PADDQ, PSUBQ, PMULUDQ Míchání, rozbalení PSHUFLW, PSHUFHW, PSHUFD PUNPCKHQDQ, PUNPCKLQDQ Posuny PSSLDQ, PSQLDQ Přesuny MMX↔XMM MOVQ2DQ, MOVDQ2Q
Instrukce SSE2 – caching Vyhození řádky cache CLFLUSH Další instrukce pro netemporální uložení MOVNTDQ, MOVNTPD, MOVNTI, MASKMOVDQU Pořadí paměťových operací LFENCE, MFENCE Podpora hyperthreadingu u spin-locků PAUSE Hinty u skoků Statická předpověď úspěšnosti skoku
Instrukce SSE3 Výpočetní prostředí a stavy procesoru se proti SSE2 nezměnily Žádné nové datové typy Žádné nové registry 1 instrukce FPU Zrychlení převodu z plovoucí čárky na celé číslo 1 SIMD celočíselná instrukce 128-bitové nezarovnané čtení 9 SIMD instrukcí v plovoucí čárce Zrychlení LOAD/MOVE/DUPLICATE Pakované sčítání a odčítání Horizontální sčítání a odčítání 2 synchronizační instrukce
Instrukce SSE3 – další módy SIMD operací Asymetrické zpracování Horizontální zpracování
Instrukce SSE3 – I FISTTP LDDQU MOVSHDUP, MOVSLDUP, MOVDDUP FPU konverze na celé číslo FISTTP Načtení nezarovnaného 128-bitového celého čísla LDDQU Pomnožení MOVSHDUP, MOVSLDUP, MOVDDUP
Instrukce SSE3 – II Asymetrické operace Horizontální operace ADDSUBPS, ADDSUBPD Horizontální operace HADDPS, HSUBPS, HADDPD, HSUBPD
Instrukce SSE3 – synchronizace Instrukce MONITOR a MWAIT Dostupné na EPL=0 Podmíněně dostupné na vyšším EPL MONITOR Nastaví HW monitoring zápisu na adresu udanou v DS:EAX (lze použít segmentové prefixy) Rozsah adres určen implementací, lze zjistit pomocí CPUID V ECX jsou volitelná rozšíření, v EDX volitelná nápověda Aktuálně není nic definováno MWAIT Čeká na zápis na adresu nastavenou MONITORem V ECX jsou volitelná rozšíření, v EAX volitelné nápovědy (např. požadovaný stav CPU)
Instrukce SSE4.1 Výpočetní prostředí a stavy procesoru se proti SSE3 nezměnily 2 instrukce pro násobení packed dword 2 instrukce pro skalární součin 1 instrukce pro čtení streamů 6 instrukcí pro míchání 8 instrukcí pro celočíselné MIN/MAX 4 instrukce s řiditelným zaokrouhlením 7 instrukcí pro přesuny mezi obecnými a XMM registry 12 instrukcí pro konverzi celočíselných typů 1 instrukce pro součet absolutních rozdílů 1 instrukce horizontálního vyhledávání 1 instrukce pro maskované porovnání 1 instrukce pro porovnání qwordů na rovnost 1 instrukce pro dword packing
Instrukce SSE4.2 4 instrukce pro zpracování textů PCMPESTRI, PCMPESTRM, PCMPISTRI, PCMPISTRM Vhodné pro zpracování XML dokumentů 1 instrukce pro porovnání qwordů na > 2 instrukce pro aplikační doménu CRC32, POPCNT
Intel AES instrukční sada AES instruction set Zvláštní rozšíření u CPU Intel od roku 2010, nutno identifikovat pomocí CPUID Pracuje s XMM registry Možnost volby AES-128, AES-192, AES-256 Instrukce pro kódování AESENC, AESENCLAST Instrukce pro dekódování AESDEC, AESDECLAST Instrukce pro generování klíčů AESKEYGENASSIST, AESIMC