浮点数的在机器级表示的层次上,与整型和指针有很大的不同,因此本文将其独立起来进行整理。

对应于书中的3.11小节。


1 历史

在很久之前,8086处理器上有一块8087芯片,能够提供实现完整IEEE浮点数所需的所有硬件,事实上,它是与IEEE浮点标准本身共同开发的,但是它的编程模型非常难用。

**SIMD(Single Instruction Multiple Data)**是指一条指令能够操作多个数据,是对CPU指令的扩展,主要用来进行小数据的并行操作。比如图像处理中,一个像素点的一个分量只需要小于等于8位来表示,如果我们用处理整型的64位寄存器用来处理,则只用到了低8位,造成很大浪费,如果将64位寄存器拆成8个8位的寄存器,就能同时对8个分量进行操作,则计算效率提高了8倍。这就是SIMD的主要想法,随着后续的发展,赋予的功能也越来越多。

Intel最初支持SIMD的指令集是1996年集成在Pentium里的MMX(Multi-Media Extension,多媒体扩展),它的主要目标是为了支持MPEG视频解码。MMX占用了FPU的8个80位寄存器,因此当MMX指令执行时,FPU就无法工作了。MMX只使用寄存器中尾数部分的64位,分别命名为MM0~MM7,将高16位置为1,因此它的浮点数值为NaN或inf,由此来区分寄存器是用于浮点数运算还是用于MMX。为了实现SIMD运算,MMX将64位寄存器当成两个32位、或4个16位、或8个8位寄存器来使用,只能处理整型计算。

Intel在1999年Pentium3中推出了SSE(Streaming SIMD Extensions,流式SIMD扩展),是继MMX的扩展指令集,主要用于3D图形计算,AMD后来在Athlon XP中加入了支持。这里处理器为SSE提供了自己的8个128位寄存器,称为XMM0~XMM7。这些寄存器可以用于4个单精度浮点数的SIMD运算,并且可以和MMX整数运算或x87浮点运算混合使用。 SSE指令要求数据是16字节对齐的。

Intel在2001年Pentium4中推出了SSE2进一步扩展了SSE指令集,用来提供高新能计算。支持在XMM寄存器上执行2个双精度浮点数、4个单精度浮点数,以及8/16/32位的整型SIMD运算,这也使得SIMD技术基本完善了。由于这里也支持整型的SIMD运算了,所以不需要MMX指令集了,同样也避免了占用浮点数寄存器。而AMD后来在Opteron和Athlon64中加入了支持,并且对它扩展增加了8个XMM寄存器,称为XMM8~XMM15,但是需要切换到64位模式(x86-64/AMD64)才可以使用这些寄存器。Intel后来在其Intel 64架构中也增加了对x86-64的支持。

Intel在2004年Pentium4E Prescott推出了SSE3,主要用于科学计算,AMD在Athlon64的第五个版本、Venice也加入了支持。这个指令集扩展的指令包含寄存器的局部位之间的运算,例如高位和低位之间的加减运算;浮点数到整数的转换,以及对超线程技术的支持。

Intel在2006年Core Duo推出了SSSE3,只是对SSE3指令集的额外扩充。

Intel在2007年Core2 Duo Penryn推出了SSE4,AMD也开发了属于自己的SSE4a多媒体指令集,并内建在Phenom与Opteron等K10架构处理器中,不过无法与Intel的SSE4系列指令集兼容。SSE4新增了了很多指令,并且优化了数据移动,能够支持不对齐的数据移动。

从上面我们可以看出,都是Intel首先提出新的指令集,而后AMD提供支持。而在SSE5指令集是2007年8月首先由AMD抢先提出的,则Intel不支持SSE5,也不开发SSE5指令集,转而在2008年3月份提出了AVX指令集。在SSE5中有几项革新:3操作数、4操作数指令,置换与条件移动指令,乘法指令以及其他一系列解决现有SSE指令集缺陷的新指令。

Intel在2008年3月份提出了AVX指令集(Advanced Vector Extension,高级向量扩展),它是SSE延伸架构,将SSE中的16个128位XMM寄存器扩展位16个256位YMM寄存器,增加了一倍的运算效率。包含了AMD提出的SSE5的工鞥呢,只是实现形式不同,并且AVX还加入了一些SSE5没有的特性:SIMD浮点指令长度加倍,为旧版SSE指令增加3操作数指令支持,为未来的指令扩展预留大量OpCode空间等。由于SSE5和AVX指令集功能类似,并且AVX包含更多的优秀特性,因此AMD决定支持AVX指令集。

**总结:**SSE和AVX都提供了支持SIMD的指令集,使得可以在物理层面上实现同时对多个整型和浮点数进行并行运算,SSE有独立的16个128位XMM寄存器,AVX进一步扩展得到16个256位YMM寄存器,每个XMM寄存器都是对应的YMM寄存器的低128位。

我们这里主要讨论AVX2,即AVX第二版。

参考:

Sinaean Dean:SIMD指令集