这是一条典型的FMA3指令,它的运算方式是:ymm0=(ymm1*[mem]) + ymm0。然而,同样的运算对应的FMA4指令的语法则是:
vfmaddps ymm0, ymm1,ymmword ptr[mem],ymm0
从上例执行fused-mult iply-add操作中我们已经可以隐约看出Intel和AMD在指令设计中的差异。再以上面的VFMADDSD指令为例:
在AMD的FMA4设计中,只存在这种模式:
VFMADDSD dest,src1,src2,src3→dest=src1*src2+src3
无论指令操作数如何变化都是按照这个种模式进行运算。这种4个操作数的设计模式提供了更大的灵活性。需要使用特定的操作数运算,只需改变操作数的位置便可实现了。
在Intel的FMA3设计中,存在3种运算模式:
VFMADD132SD dest, src1,src2→dest = dest*src2+src1
VFMADD213SD dest, src1,src2→dest =dest*src1+src2
VFMADD231SD dest, src1,src2→dest=src1*src2+dest
FMA3指令通过对指令mnemonic(助记符)的修饰达到实现多种运算模式的目的,在这种情况下产生了3条opcode码,这是3条不同的指令opcode,可是实际上只进行了一种运算,就是fused-multiply-add(融合乘加运算)。它的好处是:灵活多样,在某些指令中已经赋值给某个寄存器的情况下,可以从中选择一种合适的指令来执行fused-multiply-add运算,来保证某一个操作数不被改变。弊端是:多增加了opcode码,可能会让人感觉有些混乱。并且更重要的是会改变dest操作数原有的值。
不过,总体来说FMA3和FMA4的设计是殊途同归,目的和意图是一样的。Intel提供了96条FMA3指令,其中36条256位浮点ve ctor运算,60条128位的浮点运算,包括:vector数据与scalar数据。AMD提供了64条FMA4指令,其中24条256位浮点vector运算,40条128位的浮点运算,包括:vector数据与scalar数据。实际上FMA4与FMA3指令在规格上是一一对应的。表面上看FMA4比FMA3少了32条指令,其实这是因为FMA3指令采用了多个opcode的设计方案,这才导至了FMA3指令比FMA4指令多出了32条,但这完全不影响FMA3与FMA4指令是一一对应的事实。可是这样又重新步入了指令斗争的漩涡。理论上说支持4个操作数的FMA4设计更为优越,灵活性更大,并且重要的是FMA4并不改变dest操作数原有的值。但实际情况中FMA3与FMA4谁胜谁负只有等待2013年Haswell微架构推出之后以见分晓。
Intel从Westmere微架构处理器开始就加入了对AES(AES-NI)指令和CLMUL指令的支持,而AMD也将在推土机微架构处理器中提供对AES和CLMUL指令的支持。
AES指令
在2010年5月,Int el更新了官方术语,将AES称为AES-NI(AESNew Instructions),在发布的AESNI指令集中分两个版本各6条指令:
AES版本,也就是S SE版本,它使用了原来的SSE指令的编码规则,仅支持2个操作数,在处理器的CPUID标志中只需要为支持AES即可。AES版本有6 条指令,分别为:AESENC,AESENCLAST,AESDEC,AESDECLAST,AESKEYGENASSIST以及AESIMC。
AVX版本,使用了AVX指令的编码规则,支持3个操作数,在处理器CPUID标志中需要同时支持AES与AVX标志。对应的AVX版本也有6条指令,分别为:VAESENC,VAESENCLAST,VAESDEC, VAESDECLAST,VAESKEYGENASSIST以及VAESIMC。
AES-NI指令从硬件层上支持加密、解密运算,这有软件层上运算无法比拟的效能优势,其中4条AES-NI指令是对round进行加密、解密,2条AES-NI指令用来产生round key。
CLMUL指令
CLMUL指令执行的是Carry-less multiplication(无进位乘)操作,实际上做的是复杂的二进制多项式乘法。CLMUL也分为SSE版本和AVX版本各1条,分为:PCLMULQDQ(SSE版本)以及VPCLMULQDQ(AVX版本)。CLMUL类似于AES-NI指令在加密、解密方面得到广泛的应用。
AMD在2007年公布SSE5指令集规范,SSE5指令是原生的128位设计,提供了几大特色:
浮点multiply-add/subtract运算;整数multiply-add/subtract运算;整数horizontal-add/subtract运算;矢量条件move操作;整数rotate和shift操作;浮点和整数comparison操作;test操作;round操作;convert操作
事实上XOP指令集和FMA指令集都脱胎于SSE5指令集,它们是在SSE5指令集的基础上,使用了与AVX指令同样的编码设计规则重新设计的指令集。而原来定义的SSE5指令集已经宣告废止。现在的XOP指令与SSE5定义的指令格式已经大相庭径。也就是说同FAM一样,XOP指令集中大量的指令都是从SSE5分离出来的整数运算指令,它的特色包括:
1.XOP指令集原生是128位的设计:在256位执行环境中,指令使用128位的xmm寄存器,结果会使相应的ymm寄存器高128位清0。只有少数指令会使用256位的ymm寄存器
2.提供强大的integer(整数)运算:将SSE5指令中的integer运算分离形成XOP指令,主要体现在多样的整数multiply-add/subtract运算;整数rotate与shift运算;以及多样的comparison与test运算。
3.引进3个byes的XOP pref ix编码设计方案:这个设计方案来源于AVX指令集,舍弃了原来SSE5指令集中的SIMD prefix与escape opcode,XOPprefix使用了8F这个opcode。
XOP指令的integer运算
与AVX指令强大的f loat(浮点)运算形成鲜明的对比,XOP指令着重于integer(整数)运算,包括:
multiply-add/subtract运算,它执行的是:整数的 (a*b)+c
multiply-add-accumulate运算,这是一个相乘后相加再累加的运算。
Horizontal add/subtract运算:这类指令只有两个操作数,在源操作数内进行加/减运算。
Vector conditional move操作:实现了在bit级别的条件选择赋值操作vpcmov指令。
packed integer rotate/shift操作:这类指令分为shift(位移)和rotate(循环)两类操作,每类操作可以实现多种元素单位,包括:byte,word,doubleword以及quadword这4种元素。shift操作实现了logic(逻辑)位移以及arithmetic(算术)位数,其意义与通用指令中的logic/arithmetic位移是一致的。
packed integer comparison操作:这类比较指令分为unsigned(无符号数)比较和singed(符号数)比较,同样操作在byte,word,doubleword以及quadword元素大小。
fraction extract指令:后一部分是提取浮点数中的小数(或者分数)部分,这是XOP指令中少量的浮点数处理指令。这些指令将提供单精度或双精度浮点数的分数部分,结果放入目标寄存器相应的元素大小部分。