Single Instruction Multiple Data,簡稱SIMD。SIMD描述的是微處理器中單條指令能完成對數據的並行處理。SIMD所使用的是特殊的寄存器,一個寄存器上存儲有多個數據,在進行SIMD運算時,這些數據會被分別進行處理,以此實現了數據的並行處理。
MMX
Intel的第一個SIMD指令集是MultiMedia eXtensions(MMX),在1997年推出。MMX指令主要使用的寄存器為 MM0 ~ MM7,大小為64-bit,這些寄存器是浮點寄存器ST0~ST7(80-bit)的一部分,因此MMX與浮點運算不能同時進行。
Register | 79 - 64 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MMX指令能一次性地操作1個64-bit的數據、或者兩個32-bit的數據、或者4個16-bit的數據、或者8個8-bit的數據。
|
Description | ||||||||||||||||
|
A Single 64-bit Quadword | ||||||||||||||||
|
2 32-bit Doublewords | ||||||||||||||||
|
4 16-bit Words | ||||||||||||||||
|
8 8-bit Bytes |
MMX的指令除了 emms , movd 以及 movq 之外,其余都以字母p開頭,字母p代表packed,即表示操作多個數據。MMX指令處理的數據皆為整型,不能處理浮點數據。
SSE
Intel於1999年在Pentium III時對SIMD做了擴展,名為Streaming SIMD eXtensions(SSE),AMD則是在2001年發布的Athlon XP開始支持SSE。與MMX不同,SSE采用了獨立的寄存器組 XMM0 ~ XMM7,64位模式下為 XMM0 ~ XMM15 ,並且這些寄存器的長度也增加到了128-bit。另外還增加了一個32-bit的控制寄存器 MXCSR ,這個寄存器主要用於對SSE寄存器/指令進行控制,也有flag功能。
|
Description | ||||||||
|
4 Single-Precisions |
SSE對MMX處理整型數據的指令做了擴展,添加了幾條用於處理整型數據的指令,同樣以字母p開頭。不過SSE新增指令大多是對浮點數據並行處理的指令,這類指令以兩個字母ss或者ps為結尾。ss代表了scalar single-precision,ps代表了packed single-precision。single-precision就是一個32-bit的浮點數,也就是說一個XMM寄存器可以存儲4個single-precision,scalar表示只處理最低位的那個浮點數,packed表示處理全部四個浮點數。
此外SSE也增加了幾條內存操作相關的指令:MASKMOVQ, MOVNTQ, MOVNTPS(不經過cache直接寫回內存),PREFETCHh(從內存讀取數據到cache),SFENCE(用於保證位於SFENCE指令前的store指令先於SFENCE后的store指令完成)。
在SSE當中,MMX只能操作MMX寄存器,即以字母p開頭的指令只能操作MMX寄存器。XMM寄存器專門用於浮點數據的並行處理。
SSE2
2000年,Intel從Pentium 4微處理器開始首次引入SSE2,AMD則是在2003年開始支持SSE2。SSE2相比前兩代的SIMD擴展有兩方面的大改進。
在SSE時加入的128-bit XMM寄存器組原本只能用於浮點數據的並行處理,而更常用的MMX指令集只能操作64-bit的MMX寄存器組,這樣造成了資源的浪費。因此在SSE2中,允許128-bit的XMM寄存器組存儲整型數據,MMX指令集可以對XMM寄存器組進行整型數據的操作,如此一來整型數據的並行處理能力增加了一倍。
MMX指令集中,原來並行處理的最大整型為32-bit的Doubleword,而XMM寄存器大小為128-bit,能同時處理兩個64-bit的Quadword,所以SSE2增加了可以並行處理64-bit整型數據的指令,這些指令一般以q為結尾,意為 quadword。
|
Description | ||||||||||||||||||||||||||||||||
|
128-bit | ||||||||||||||||||||||||||||||||
|
A Double 64-bit Quadword | ||||||||||||||||||||||||||||||||
|
4 32-bit Doublewords | ||||||||||||||||||||||||||||||||
|
8 16-bit Words | ||||||||||||||||||||||||||||||||
|
16 8-bit Bytes |
另一方面,SSE2擴展了浮點類型數據的處理指令。SSE中只能處理長度為32-bit的Single-Precision,SSE2把浮點數據的長度擴展到了64-bit的Double-Precision。這類處理64-bit浮點數據類型的SIMD指令以sd或者pd結尾,分別代表scalar double-precision與packed double-precision。
|
Description | ||||
|
2 Double-Precisions |
此外,SSE2也增加了一些控制指令。
SSE3
2004年,在Intel發布的Pentium 4 Prescott微處理器上對SIMD擴展到了SSE3,AMD則是在2005年開始支持了SSE3。SSE3所做的擴展內容並不多,只是增加了13條新指令。不過這些都不是太常用的指令,其中包括浮點水平算術運算、水平復制移動等。
SSSE3
Intel Core 2微處理器時推出了Supplemental Streaming SIMD eXtensions (SSSE3)。增加的指令也不多,包括整型水平算術運算以及較為常用的絕對值運算等。
SSE4
SSE4指令集在2006年發布,並在2007年初實現在了Intel以及AMD的處理器上。SSE4包括三大類:
- SSE4.1 主要目的是用於提升音視頻、圖像、3D等方向的數據處理的性能。如MPSADBW在尋找兩張圖像的匹配塊時能起到很大的作用。
- SSE4.2 主要目的是用於提升字符串、文本等(字符比對)方面的數據處理性能。
- SSE4a 是AMD專用的擴展。主要添加了一些位處理指令。
AVX
Advanced Vector eXtentions(AVX)在2008年由Intel與AMD提出,並於2011年分別在Sandy Bridge以及Bulldozer架構上提供支持。AVX的主要改進在於對寄存器長度的擴展以及提供了更靈活的指令集。
AVX對 XMM 寄存器做了擴展,從原來的128-bit擴展到了256-bit,256-bit的寄存器命名為 YMM 。YMM的低128-bit是與XMM混用的。
Register |
|
|
|
|
|
AVX對SSE指令集做了擴展,對SSE指令添加了前綴v(VEX)。我傳統的x86指令很多都是只有兩個操作數:op dest, src,兩個操作數在進行運算后得到的結果會把dest給覆蓋,如果后續的操作需要原來的dest來執行某些操作,則必須多添加一條指令把dest中的數據提取到別的寄存器。AVX擴展為了處理這種情況,新增了一個操作數專門用於存儲處理結果 vop dest,src1, src2 ,如此一來使得兩條指令變成一條指令,減少了的數據的移動,並且這類指令也能進行micro-fusion。
VEX前綴的指令集可以操作大多數的XMM(VEX.128)以及YMM(VEX.256)。不過AVX的擴展指令集中並不包括整型數據的處理指令,VEX前綴只能加在浮點指令上。也就是說AVX只支持256-bit的SIMD浮點數據的並行處理。
AVX2
2013年Intel發布的Haswell處理器上開始支持AVX2,AMD則是2015年的Excavator處理器。
AVX2主要為處理整型數據的指令提供VEX前綴,為256-bit的SIMD整型數據的並行處理提供支持。
AVX-512
AVX-512由Intel在2013年提出,並在2016年推出首次支持了AVX-512的處理器Xeon Phi x200 (Knights Landing)。
如擴展名所示,AVX-512主要改進是把SIMD寄存器擴展到了512-bit。其主要新增的特性可以歸納如下:
- 把 YMM 擴展到了512-bit的 ZMM ,ZMM的低256-bit與YMM混用。
- YMM / ZMM 寄存器的數量增加到了32個,其中 YMM8 ~ YMM31 / ZMM8 ~ ZMM31 只有CPU工作在64位模式下才能使用。
- 支持opmask。SIMD指令一般都是操作寄存器上的多組數據,此處增加的opmask就是用於控制其中的各組數據是否需要執行,格式如:VADDPS zmm1 {k1}{z}, zmm2, zmm3,當中的k1就是opmask寄存器,z表示對不進行操作的那組數據,往目標寄存器寫0。一共有7個opmask register(k0 ~ k7)。
- 操作512-bit的ZMM時使用的前綴為EVEX,實際上一些匯編器用的都是v作為指令前綴。
Register |
|
|
|
|
|
|
|
AESNI & SHA Extensions
Advanced Encryption Standard New Instructions(AESNI)擴展在2008年由Intel與AMD提出,目的是用於AES的加密解密。在2010年Intel在其Westmere(32nm Nehalem)架構上首次支持該指令集,而AMD則是2011年在Bulldozer架構上首次支持。
Secure Hash Algorithm (SHA)擴展在2013年引入到Intel指令集中,主要用於SHA-1以及SHA-256的計算。2016年,Intel與AMD分別在他們的Goldmont以及Ryzen架構中支持SHA擴展指令集。
Reference:
Intel 64 and IA-32 Architectures Software Developer's Manual
New Instructions Supporting the Secure Hash Algorithm on Intel® Architecture Processors