AVX (Advanced Vector Extensions) – rozszerzenie listy rozkazów SSE opublikowane w marcu 2008 przez Intel. Jako pierwszy procesor zawierający ten zestaw instrukcji miał się pojawić w pierwszym kwartale 2011 roku i być oparty na architekturze Sandy Bridge tej firmy. AMD zapowiadał wprowadzenie procesora z AVX na trzeci kwartał 2011 roku – miałby być to układ o architekturze Bulldozer.
Rozszerzenia:
W AVX wprowadzono 256-bitowe rejestry – 2 razy większe niż wykorzystywane dotychczas w SSE. Nowych rejestrów jest 16 i w asemblerze noszą nazwy YMM0...YMM15. W dalszych wersjach AVX mogą pojawić się jeszcze większe rejestry, 512-, a nawet 1024-bitowe.
Dodano kilka rozkazów działających wyłącznie na rejestrach YMM (19 rozkazów).
Dodane czteroargumentowe rozkazy akumulujące wyniki mnożenia wektorów liczb zmiennoprzecinkowych, to znaczy wykonujące obliczenia według schematu (12 rozkazów).
Część rozkazów SSE, głównie tych działających na wektorach liczb zmiennoprzecinkowych, może wykonywać działania na rejestrach YMM (88 rozkazów).
Rozszerzone kodowanie rozkazów, dzięki któremu możliwe stało się wykonywanie niektórych instrukcji SSE w wariancie trójargumentowym lub czteroargumentowym. Dotychczas wszystkie rozkazy były dwuargumentowe, z czego jeden był docelowy (nadpisywany) i często zachodziła konieczność jego zapisania/przepisania do innego rejestru lub pamięci, jeśli musiał zostać wykorzystany w dalszej części obliczeń – w wariancie trójargumentowym można wprost wskazać docelowy rejestr (rozwiązanie zapożyczone z architektury RISC) (166 rozkazów).
Rejestry
Mikroprocesor pracujący w trybie 32-bitowym ma dostęp do pierwszych 8 rejestrów (0..7), w trybie 64-bitowym do wszystkich. Istniejące rejestry SSE (XMM0...XMM7) zostały zamapowane na młodsze 128 bitów rejestrów YMM0...YMM7.
Typy danych
W związku z dwukrotnym poszerzeniem rejestru pojawiły się nowe typy wektorowe tylko dla liczb zmiennoprzecinkowych:
Mnemoniki rozkazów AVX oraz SSE działających na 256-bitowych rejestrach rozpoczynają się literą V. Typ danych, na jakich działają, określa sufiks:
PS, PD – wektor liczb zmiennoprzecinkowych,
SS, SD – skalar (pierwszy element wektora), czyli liczba zmiennoprzecinkowa odpowiednio pojedynczej i podwójnej precyzji
Mnemoniki rozkazów akumulujących wyniki mnożenia rozpoczynają się od VFM lub VFNM, natomiast mnemoniki rozkazów wspomagających szyfrowanie od AES.
Rozkazy AVX
Instrukcje AVX działają na rejestrach YMM, niektóre również na XMM.
Nowe rozkazy
Instrukcja
Działanie
VBROADCASTSS VBROADCASTSD VBROADCASTF128
powielenie liczby 32-, 64- lub 128-bitowej pobranej z pamięci w rejestrze XMM lub YMM
VEXTRACTF128
przepisanie starszych lub młodszych 128 bitów z rejestru YMM do pamięci lub rejestru XMM (zerując starsze 128 bitów stowarzyszonego z nim rejestru YMM)
VINSERTF128
wpisanie 128 bitów z rejestru XMM lub pamięci do starszej lub młodszej połówki źródłowego rejestru YMM i przepisanie tak utworzonego wektora docelowego YMM
VMASKMOVPS VMASKMOV
przesłanie wybranych elementów z do pamięci (przesłania 128 lub 256-bitowe)
dowolna permutacja elementów z dwóch wektorów; dodatkowo można wskazać które elementy wektora wynikowego mają zostać wyzerowane
PCLMULQDQ
ang. carry-less-multiplication – mnożenie liczb binarnych 64-bitowych[1], w którym przy dodawaniu nie uwzględnia się przeniesień (kolejne bity wyniku to efekt wykonania pewnej liczby różnic symetrycznych)
VPTESTPS VPTESTPD
rozkazy podobne do VPTEST (PTEST, patrz opis SSE4), przy czym działania bitowe nie są przeprowadzane na całych rejestrach, lecz na bitach znaków liczb zmiennoprzecinkowych
VZEROALL
w trybie 64-bitowym wyzerowanie wszystkich rejestrów YMM, w trybie 32-bitowym – YMM0..YMM7
VZEROUPPER
w trybie 64-bitowym wyzerowanie bitów 128..255 we wszystkich rejestrach YMM, w trybie 32-bitowym – w rejestrach YMM0..YMM7
VLDMXCSR VSTMXCSR
załadowanie/zapis zawartości rejestru kontrolnego z/do pamięci
Akumulujące wyniki mnożenia (FMA)
Liczba rozkazów należących do tej grupy wynosi 12. Wszystkie są czteroargumentowe VFMxxxxx w, x, y, z i wykonują działanie według schematu
Instrukcje skalarne, czyli działające na pierwszym elemencie wektora (sufiks SD lub SS), zachowują się inaczej niż instrukcje skalarne SSE: wpisują wartość zero na pozostałe pozycje wektora wynikowego, podczas gdy w SSE przepisywane są elementy jednego z argumentów.
Lista rozkazów FMA:
Instrukcja
Działanie
VFMADDPD VFMADDPS VFMADDSD VFMADDSS
lub
VFMSUBPD VFMSUBPS VFMSUBSD VFMSUBSS
VFNMADDPD VFNMADDPS VFNMADDSD VFNMADDSS
VFNMSUBPD VFNMSUBPS VFNMSUBSD VFNMSUBSS
VFMADDSUBPD VFMADDSUBPS
przy czym dla parzystego wykonywane jest dodawanie, dla nieparzystego – odejmowanie
VFMSUBADDPD VFMSUBADDPS
przy czym dla nieparzystego wykonywane jest dodawanie, dla parzystego – odejmowanie
Wspomagające szyfrowanie algorytmem AES
AESDEC, AESDECLAST – deszyfrowanie
AESENC, AESENCLAST – szyfrowanie
AESIMC
AESKEYGENASSIST
Rozszerzone rozkazy SSE
AVX rozszerza możliwości instrukcji SSE na dwa sposoby:
umożliwia przeprowadzanie obliczeń na dwa razy szerszych rejestrach YMM
rozszerza liczbę argumentów z dwóch na trzy lub trzech na cztery
Rozkazy SSE mogące dodatkowo działać na rejestrach YMM
Instrukcja
Działanie
VCVTDQ2PD VCVTDQ2PS
konwersja 32-bitowych liczb całkowitych na zmiennoprzecinkowe
VCVTPD2DQ VCVTTPD2DQ VCVTPS2DQ VCVTTPS2DQ
konwersja liczb zmiennoprzecinkowych podwójnej/pojedynczej precyzji na 32-bitowe liczby całkowite
VCVTPD2PS
konwersja liczb zmiennoprzecinkowych podwójnej precyzji na liczby pojedynczej precyzji
VCVTPS2PD
konwersja liczb zmiennoprzecinkowych pojedynczej precyzji na liczby podwójnej precyzji
VLDDQU VMOVDQU VMOVUPD VMOVUPS
załadowanie 256 bitów z pamięci (adresy pamięci dowolne)
VMOVPAD VMOVAPS VMOVDQA
załadowanie 256 bitów z pamięci (adresy pamięci wyrównane do granicy 256 bitów)
VMOVDDUP
powielenie elementów
VMOVMSKPD
utworzenie 4-bitowej maski bitowej z najstarszych bitów wektora liczb zmiennoprzecinkowych podwójnej precyzji (4 × 64 bity)
VMOVMSKPS
utworzenie 8-bitowej maski bitowej z najstarszych bitów wektora liczb zmiennoprzecinkowych pojedynczej precyzji (8 × 32 bity)
VMOVSHDUP VMOVSLDUP
powielenie elementów o nieparzystych/parzystych indeksach w wektorze liczb 32-bitowych
VPTEST
VRCPPS
aproksymacja odwrotności
VRSQRTPS
aproksymacja odwrotności pierwiastka
VROUNDPD VROUNDPS
zaokrąglanie
VSHUFPD VSHUFPS
utworzenie wektora z elementów dwóch innych wekorów
VSQRTPD VSQRTPS
pierwiastek
VUNPCKHPD VUNPCKHPS VUNPCKLPD VUNPCKLPS
Trójargumentowe instrukcje SSE mogące działać na rejestrach XMM oraz YMM
Instrukcja
Działanie
VADDPD VADDPS
dodawanie
VSUBPD VSUBPS
odejmowanie
VMULPD VMULPS VMULSD VMULSS
mnożenie
VDIVPD VDIVPS VDIVSD VDIVSS
dzielenie
VSUBADDPD VSUBADDPS
naprzemienne dodawanie i odejmowanie
VHADDPD VHADDPS
dodawanie sąsiednich elementów
VHSUBPD VHSUBPS
odejmowanie sąsiednich elementów
VMAXPD VMAXPS VMINPD VMINPS
wybranie maksymalnych/minimalnych wartości z dwóch wektorów
VANDPD VANDPS
iloczyn bitowy
VANDNPD VANDNPS
iloczyn bitowy z jednym z argumentów zanegowanym
VORPD VORPS
suma bitowa
VXORPD VXORPS
różnica symetryczna
VCMPPD VCMPPS VCMPSD VCMPSS
porównania (rozszerzono także z 8 do 32 liczbę relacji, które można sprawdzić)
VCVTSD2SS
konwersja liczby zmiennoprzecinkowej podwójnej precyzji na pojedynczej precyzji
VCVTSS2SD
konwersja liczby zmiennoprzecinkowej pojedynczej precyzji na podwójnej precyzji
VMOVSD VMOVSS
wpisanie pojedynczej liczby zmiennoprzecinkowej podwójnej/pojedynczej precyzji
VRCPSS
aproksymacja odwrotności
VRSQRTSS
aproksymacja odwrotności pierwiastka
VROUNDSD VROUNDSS
zaokrąglanie
VSQRTSD VSQRTSS
pierwiastek
VPACKSSDW VPACKSSWB
konwersja liczb całkowitych 32-bitowych na 16-bitowe/16-bitowych na 8-bitowe; wyniki są nasycane
VPACKUSDW VPACKUSWB
konwersja liczb całkowitych 32-bitowych na 16-bitowe bez znaku/16-bitowych na 8-bitowe bez znaku; wyniki są nasycane
Trójargumentowe instrukcje SSE mogące działać wyłącznie na rejestrach XMM
Rozkazy działające na wektorach liczb zmiennoprzecinkowych:
Instrukcja
Działanie
VADDSD VADDSS
dodawanie skalarne
VSUBSD VSUBSS
odejmowanie skalarne
VMAXSD VMAXSS VMINSD VMINSS
wybranie maksymalnych/minimalnych wartości z dwóch skalarów
VMOVHLPS
przepisanie starszych 64 bitów (64..127) rejestru XMM na najmłodsze pozycje (0..63), wyzerowanie starszych 128 bitów stowarzyszonego z nim rejestru YMM
VMOVLHPS
przepisanie młodszych 64 bitów (0..63) rejestru XMM na najmłodsze pozycje (0..63), wyzerowanie starszych 128 bitów stowarzyszonego z nim rejestru YMM
VMOVHPD VMOVHPS
skopiowanie bitów młodszych 64 bitów (0..63) argumentu na pozycje 0..63 i 64..127 rejestru XMM, wyzerowanie starszych 128 bitów stowarzyszonego z nim rejestru YMM
VMOVLPD VMOVLPS
Rozkazy działające na wektorach liczb całkowitych:
Instrukcja
Działanie
VMPSADBW
wyznaczenie 8 kolejnych sum modułów różnic (dokładny opis działania w artykule SSE4)
VPADDB VPADDW VPADDD VPADDQ
dodawanie wektorów liczb całkowitych (8-, 16-, 32- i 64-bitowych)
VPSUBB VPSUBW VPSUBD VPSUBQ
odejmowanie wektorów liczb całkowitych (8-, 16-, 32- i 64-bitowych)
VPADDSB VPADDSW
dodawanie z nasyceniem wektorów liczb całkowitych ze znakiem (8- i 16-bitowych)
VPSUBSB VPSUBSW
odejmowanie z nasyceniem wektorów liczb całkowitych ze znakiem (8- i 16-bitowych)
VPSUBUSB VPSUBUSW
odejmowanie z nasyceniem wektorów liczb całkowitych bez znaku (8- i 16-bitowych)
VPHADDW VPHADDD
dodawanie sąsiednich elementów wektorów liczb całkowitych (16- i 32-bitowych)
VPHSUBW VPHSUBD
odejmowanie sąsiednich elementów wektorów liczb całkowitych (16- i 32-bitowych)
VPHADDSW
dodawanie z nasyceniem sąsiednich elementów wektorów 16-bitowych liczb całkowitych
VPHSUBSW
odejmowanie z nasyceniem sąsiednich elementów wektorów 16-bitowych liczb całkowitych
VPADDUSB VPADDUSW
dodawanie z nasyceniem wektorów liczb całkowitych bez znaku (8- i 16-bitowych)
VPALIGNR
połączenie dwóch wektorów 16-bajtowych w 32-bitowy i wybranie z niego zakresu 16 bajtów
VPAND VPOR VPXOR VPANDN
działania bitowe: iloczyn, suma, różnica symetryczna, iloczyn z zanegowanym jednym z argumentów
VPAVGB VPAVGW
średnia arytmetyczna wektorów
VPCMPEQB VPCMPEQW VPCMPEQD VPCMPEQQ
testowanie relacji równości liczb całkowitych (8-, 16-, 32- i 64-bitowych)
VPCMPGTB VPCMPGTW VPCMPGTD VPCMPGTQ
testowanie relacji większości liczb całkowitych ze znakiem (8-, 16-, 32- i 64-bitowych)
VPINSRB VPINSRW VPINSRD VPINSRQ
VMPADDWD VMPADDUBSW
mnożenie wektorowe, następnie dodawanie sąsiednich elementów
VPMAXSB VPMINSB VPMAXSW VPMINSW VPMAXSD VPMINSD
wybranie maksymalnych/minimalnych liczb całkowitych ze znakiem (z wektorów 8-, 16- i 32-bitowych liczb)