SSE3
Streaming SIMD Extensions 3 (SSE3, oznaczany również przez firmę Intel jako Prescott New Instructions lub PNI) – zestaw instrukcji SIMD wykorzystywany w architekturze IA-32. Wcześniejsze zestawy SIMD stosowane na platformie x86, od najstarszej to: MMX, 3DNow! (używany tylko przez AMD), SSE i SSE2.
SSE3 wprowadza 13 nowych rozkazów w stosunku do swojego poprzednika SSE2, są to:
FISTTP
– do konwersji liczb zmiennoprzecinkowych do całkowitychADDSUBPS
,ADDSUBPD
,MOVSLDUP
,MOVSHDUP
,MOVDDUP
– do arytmetyki zespolonejLDDQU
– do kodowania wideoHADDPS
,HSUBPS
,HADDPD
,HSUBPD
– do grafiki (SIMD FP/AOS)MONITOR
,MWAIT
– do synchronizacji wątków
Intel wprowadził SSE3 2 lutego 2004 roku wraz z procesorem Pentium 4 Prescott, natomiast firma AMD w procesorach Athlon 64 od wersji E.
Nowe rozkazy
edytujNowe rozkazy:
- rozkazy wektorowe działające albo na wektorach liczb zmiennoprzecinkowych pojedynczej albo podwójnej precyzji (tj. wektory 4 × 32 bity lub 2 × 64 bity):
ADDSUBPS
ADDSUBPD
HADDPS
,HSUBPS
HADDPD
,HSUBPD
MOVSLDUP
,MOVSHDUP
MOVDDUP
FISTTP
– nowy rozkaz FPULDDQU
MONITOR
iMWAIT
Przed wprowadzaniem SSE3 prawie wszystkie rozkazy arytmetyczne występujące w MMX, SSE, SSE2 działały, jak to określa Intel, „pionowo” (ang. vertical), tj. argumentami działań zawsze są elementy z dwóch wektorów. Natomiast w SSE3 pojawiły się rozkazy działające „poziomo” (ang. horizontal) — argumentami operacji arytmetycznych są elementy tego samego wektora; te instrukcje to: HADDPS
, HADDPD
, HSUBPS
, HSUBPD
.
FISTTP
edytujRozkaz koprocesora arytmetycznego zamieniający liczbę zmiennoprzecinkową zapisaną w wierzchołku stosu na liczbę całkowitą ze znakiem; trybem zaokrąglania zawsze jest ucinanie (ang. chop), niezależnie od ustawień zapisanych w rejestrze kontrolnym FPU. Liczba całkowita może być 16-, 32- lub 64-bitowa, zależnie od argumentu.
Zgłaszany jest wyjątek w przypadku, gdy konwersja jest niemożliwa (wartość przekracza zakres liczby całkowitej, albo jest klasy plus/minus nieskończoność lub NaN).
Rozkaz FISTTP
to uproszczona wersja istniejącej instrukcji FISTP
, w której tryb zaokrąglania sterowany jest poprzez słowo kontrolne koprocesora – jego ewentualna zmiana jest kosztowna (trzeba wykonać kilka lub kilkanaście dodatkowych instrukcji: zachować bieżące ustawienia, włączyć inny tryb zaokrąglania, wykonać FISTP
, przywrócić poprzedni tryb).
ADDSUBPS
edytujRozkaz działa na dwóch wektorach liczb zmiennoprzecinkowych pojedynczej precyzji. Wykonywane jest dodawanie elementów o nieparzystych indeksach, odejmowanie – parzystych. Działania realizowane przez ADDSUBPS xmm1, xmm2
:
xmm1[0] := xmm1[0] - xmm2[0] xmm1[1] := xmm1[1] + xmm2[1] xmm1[2] := xmm1[2] - xmm2[2] xmm1[3] := xmm1[3] + xmm2[3]
ADDSUBPD
edytujRozkaz analogiczny do ADDSUBPS
, działa na dwóch wektorach liczb zmiennoprzecinkowych podwójnej precyzji. Działania realizowane przez ADDSUBPD xmm1, xmm2
:
xmm1[0] := xmm1[0] - xmm2[0] xmm1[1] := xmm1[1] + xmm2[1]
HADDPS, HSUBPS
edytujRozkazy działają na wektorach liczb zmiennoprzecinkowych pojedynczej precyzji. HADDPS
dodaje, zaś HSUBPS
odejmuje sąsiednie elementy wektorów, tzn. HADDPS xmm1, xmm2
wykonuje:
temp[0] := xmm1[0] + xmm1[1] temp[1] := xmm1[2] + xmm1[3] temp[2] := xmm2[0] + xmm2[1] temp[3] := xmm2[2] + xmm2[3] xmm1 := temp
natomiast HSUBPS xmm1, xmm2
:
temp[0] := xmm1[0] - xmm1[1] temp[1] := xmm1[2] - xmm1[3] temp[2] := xmm2[0] - xmm2[1] temp[3] := xmm2[2] - xmm2[3] xmm1 := temp
Np.:
3 2 1 0 3 2 1 0 +-----+-----+-----+-----+ +-----+-----+-----+-----+ | d | c | b | a | | h | g | f | e | +-----+-----+-----+-----+ +-----+-----+-----+-----+ xmm1 xmm2
Wynik HADDPS
:
+-----+-----+-----+-----+ xmm1 = | h+g | f+e | c+d | a+b | +-----+-----+-----+-----+
Wynik HSUBPS
:
+-----+-----+-----+-----+ xmm1 = | h-g | f-e | c-d | a-b | +-----+-----+-----+-----+
HADDPD, HSUBPD
edytujRozkazy działają na wektorach liczb zmiennoprzecinkowych podwójnej precyzji. Rozkaz HADDPD
dodaje do siebie sąsiednie elementy wektorów, natomiast HSUBPD
odejmuje. Instrukcja HADDPD xmm1, xmm2
wykonuje:
temp[0] := xmm1[0] + xmm1[1] temp[1] := xmm2[0] + xmm2[1] xmm1 := temp
natomiast HSUBPD xmm1, xmm2
:
temp[0] := xmm1[0] - xmm1[1] temp[1] := xmm2[0] - xmm2[1] xmm1 := temp
MOVSLDUP, MOVSHDUP
edytujRozkazy działają na wektorze liczb zmiennoprzecinkowych pojedynczej precyzji; rozkaz MOVSLDUP
powiela elementy o parzystych indeksach, MOVHLDUP
– o nieparzystych. Instrukcja MOVSLDUP xmm1, xmm2
wykonuje:
xmm1[0] := xmm2[0] xmm1[1] := xmm2[0] xmm1[2] := xmm2[2] xmm1[3] := xmm2[2]
natomiast MOVSHDUP xmm1, xmm2
:
xmm1[0] := xmm2[1] xmm1[1] := xmm2[1] xmm1[2] := xmm2[3] xmm1[3] := xmm2[3]
Np.
3 2 1 0 +-----+-----+-----+-----+ xmm2 = | d | c | b | a | +-----+-----+-----+-----+
Wynik MOVSLDUP
:
+-----+-----+-----+-----+ xmm1 = | c | c | a | a | +-----+-----+-----+-----+
Wynik MOVSHDUP
:
+-----+-----+-----+-----+ xmm1 = | d | d | b | b | +-----+-----+-----+-----+
MOVDDUP
edytujArgumentem rozkazu jest liczba zmiennoprzecinkowa podwójnej precyzji, która w rejestrze XMM jest powielana, tj. MOVDDUP xmm1, arg
wykonuje:
xmm1[0] := arg xmm1[1] := arg
Argumentem może być albo lokacja pamięci (wówczas czytane są 64 bity), albo rejestr XMM, wówczas brane są jego 64 najmłodsze bity.
LDDQU
edytujRozkaz ładuje 128 bitów spod adresów niewyrównanych do granicy 16 bajtów (tj. adresy mający niezerowe 4 najmłodsze bity). Rozkaz realizuje działanie analogiczne do istniejącego w SSE MOVDQU
, jednak został specjalnie zoptymalizowany do kodu o następującej charakterystyce:
- występuje spadek wydajności spowodowany częstymi odczytami obszarów znajdujących się na granicy linijek cache,
- dane są tylko odczytywane i nie mają zostać (po ewentualnej modyfikacji) z powrotem zapisane pod tym samym adresem.
W przeciwnym razie producent poleca, by nadal używać rozkazów SSE MOVDQU
lub MOVDQA
.
MONITOR i MWAIT
edytujPara rozkazów służy do efektywnego synchronizowania wątków.
Rozkaz MONITOR
ustala początkowy adres zakresu pamięci (rozmiar tego obszaru jest stały, zależny od modelu procesora), który następnie jest automatycznie monitorowany przez procesor: w przypadku wystąpienia zapisu gdziekolwiek w obserwowanym zakresie ustawiana jest wewnętrzna flaga, którą odczytuje MWAIT
.
Wykonanie rozkazu MWAIT
powoduje wejście w zoptymalizowaną sprzętową pętlę, która jest przerywana, dopiero gdy wspomniana flaga zostanie ustawiona, a więc gdy nastąpi zapis pod obserwowany adres.
Producenci procesorów mogą rozszerzać funkcjonalność tych rozkazów, dlatego m.in. możliwe jest przejście w tryb oszczędzanie energii na czas wykonywania MWAIT
.
Bibliografia
edytuj- Intel 64 and IA-32 Architectures Software Developer's Manual: Volume 2A: Instruction Set Reference, A-M (253666), maj 2007