分类:
2009-11-16 21:36:21
SSE全新定义了8个新的128位寄存器xmm0-xmm7,比MMX的64位还提高了1倍,每个寄存器可以同时装入4个32位的浮点数,因为是全新的寄存器,所以少了MMX寄存器与原浮点寄存器的切换工作,所以有了更高的执行效率。值得注意的SSE还可以对16位和8位的整数进行运算,不过这已经不是SSE应用的主流了。
在这里随便提一个Intel Compiler 8.0,这个编译器的优化能力的确是强,个人感觉大概比Visual C++ 6.0 SP6快10-20%左右,它可以针对不同的CPU作出优化,如果你是P4系列的cpu,在编译的时候加上参数/fast /QxW /Qip /Qunroll40,会有意想不到的结果,如果你再阅读一个它的用户手册,按照里面的方法稍微修改一下程序将会有更多提高,向所有崇拜极限优化的朋友推荐这款编译器。题外话少说,再次转入SSE正题,下面还是给出一个简单的例子:
在VC中使用内联汇编
float a[]={1.0,2.0,3.0,4.0};
float b[]={5.0,6.0,7.0,8.0};
_asm{
mov ecx,a;
mov edx,b;
movaps xmm0,[ecx];
movaps xmm1,[edx];
addps xmm0,xmm1;
movaps [ecx],xmm0;
}
跟MMX一样也可以不用汇编只用包含一个头文件就可以直接在C里面使用了:
#include
__m128 a = _mm_set_ps(1, 2, 3, 4)
__m128 b = _mm_set_ps(5, 6, 7, 8)
a = _mm_add_ps(a, b);
这个时候就感觉使用Intrinsics方便多了,因为它制定了好多合成的伪指令,方便了不少。
下面顺便贴一段SSE的部分指令介绍,更全的可以找Intel下载指令手册。下面这部分是引用至:
ADDPS
格式:ADDPS xmm1, xmm2/m128
功能:两组单精度数相加
算法:
DEST[31-0] = DEST[31-0] + SRC/m128[31-0] ;
DEST[63-32] = DEST[63-32] + SRC/m128[63-32] ;
DEST[95-64] = DEST[95-64] + SRC/m128[95-64] ;
DEST[127-96] = DEST[127-96] + SRC/m128[127-96];
ADDSS
格式:ADDSS xmm1, xmm2/m32
功能:低位单精度数相加
算法:
DEST[31-0] = DEST[31-0] + SRC/m32[31-0];
DEST[63-32] = DEST[63-32] ;
DEST[95-64] = DEST[95-64] ;
DEST[127-96] = DEST[127-96];
ANDNPS
格式:ANDNPS xmm1, xmm2/m128
功能:xmm1“取反”再和 xmm2/m128 求“与”运算
算法:
DEST[127-0] = NOT (DEST[127-0]) AND SRC/m128[127-0];
ANDPS
格式:ANDPS xmm1, xmm2/m128
功能:进行两个寄存器的逻辑“与”操作
算法:
DEST[127-0] AND= SRC/m128[127-0];
CMPPS
格式:CMPPS xmm1, xmm2/m128, imm8
功能:比较两个寄存器的数值,根据imm8的不同数值采用不同的比较方法
imm8 == 0, ==; imm8 == 1, <; imm8 == 2, <=; imm8 == 3, ;
imm8 == 4, !=; imm8 == 5, !<; imm8 == 6, !<=; imm8 == 7, !;
算法:
IF (imm8 = 0) THEN
OP = "EQ";
ELSEIF (imm8 = 1) THEN
OP = "LT";
ELSEIF (imm8 = 2) THEN
OP = "LE";
ELSEIF (imm8 = 3) THEN
OP = "UNORD";
ELSEIF (imm8 = 4) THEN
OP = "NE";
ELSEIF (imm8 = 5) THEN
OP = "NLT";
ELSEIF (imm8 = 6) THEN
OP = "NLE";
ELSEIF (imm8 = 7) THEN
OP = "ORD";
FI
CMP0 = DEST[31-0] OP SRC/m128[31-0];
CMP1 = DEST[63-32] OP SRC/m128[63-32];
CMP2 = DEST [95-64] OP SRC/m128[95-64];
CMP3 = DEST[127-96] OP SRC/m128[127-96];
IF (CMP0 = TRUE) THEN
DEST[31-0] = 0XFFFFFFFF;
ELSE
DEST[31-0] = 0X00000000;
FI
IF (CMP1 = TRUE) THEN
DEST[63-32] = 0XFFFFFFFF;
ELSE
DEST[63-32] = 0X00000000;
FI
IF (CMP2 = TRUE) THEN
DEST[95-64] = 0XFFFFFFFF;
ELSE
DEST[95-64] = 0X00000000;
FI
IF (CMP3 = TRUE) THEN
DEST[127-96] = 0XFFFFFFFF;
ELSE
DEST[127-96] = 0X00000000;
FI
其它:你可以使用下面的可读性良好的指令
指令 实现
CMPEQPS xmm1, xmm2; CMPPS xmm1,xmm2, 0
CMPLTPS xmm1, xmm2; CMPPS xmm1,xmm2, 1
CMPLEPS xmm1, xmm2; CMPPS xmm1,xmm2, 2
CMPUNORDPS xmm1, xmm2; CMPPS xmm1,xmm2, 3
CMPNEQPS xmm1, xmm2; CMPPS xmm1,xmm2, 4
CMPNLTPS xmm1, xmm2; CMPPS xmm1,xmm2, 5
CMPNLEPS xmm1, xmm2; CMPPS xmm1,xmm2, 6
CMPORDPS xmm1, xmm2; CMPPS xmm1,xmm2, 7
CMPSS
格式:CMPSS xmm1, xmm2/m32, imm8
功能:低位单精度数做比较
算法:算法同CMPPS相似,只不过只是针对DEST[31-0]进行操作。
同样也可以利用可读性更好的指令
指令 实现
CMPEQSS xmm1, xmm2 CMPSS xmm1,xmm2, 0
CMPLTSS xmm1, xmm2 CMPSS xmm1,xmm2, 1
CMPLESS xmm1, xmm2 CMPSS xmm1,xmm2, 2
CMPUNORDSS xmm1, xmm2 CMPSS xmm1,xmm2, 3
CMPNEQSS xmm1, xmm2 CMPSS xmm1,xmm2, 4
CMPNLTSS xmm1, xmm2 CMPSS xmm1,xmm2, 5
CMPNLESS xmm1, xmm2 CMPSS xmm1,xmm2, 6
CMPORDSS xmm1, xmm2 CMPSS xmm1,xmm2, 7
COMISS
格式:COMISS xmm1, xmm2/m32
功能:比较低位数并且设置标识位
算法:
OF = 0;
SF = 0;
AF = 0;
IF ((DEST[31-0] UNORD SRC/m32[31-0]) = TRUE) THEN
ZF = 1;
PF = 1;
CF = 1;
ELSEIF ((DEST[31-0] GTRTHAN SRC/m32[31-0]) = TRUE)THEN
ZF = 0;
PF = 0;
CF = 0;
ELSEIF ((DEST[31-0] LESSTHAN SRC/m32[31-0]) = TRUE THEN
ZF = 0;
PF = 0;
CF = 1;
ELSE
ZF = 1;
PF = 0;
CF = 0;
FI
CVTPI2PS
格式:CVTPI2PS xmm, mm/m64
功能:32位整数转变为浮点数
算法:
DEST[31-0] = (float) (SRC/m64[31-0]) ;
DEST[63-32] = (float) (SRC/m64[63-32]);
DEST[95-64] = DEST[95-64] ;
DEST[127-96] = DEST[127-96];
CVTPS2PI
格式:CVTPS2PI mm, xmm/m64
功能:低位的两个浮点数转变为整数
算法:
DEST[31-0] = (int) (SRC/m64[31-0]);
DEST[63-32]= (int) (SRC/m64[63-32]);
CVTSI2SS
格式:CVTSI2SS xmm, r/m32
功能:32位整数转变为浮点数,存入低位
算法:
DEST[31-0] = (float) (R/m32);
DEST[63-32] = DEST[63-32] ;
DEST[95-64] = DEST[95-64] ;
DEST[127-96] = DEST[127-96];
CVTSS2SI
格式:CVTSS2SI r32, xmm/m32
功能:低位的浮点数转变为32位整数
算法:
r32 = (int) (SRC/m32[31-0]);
CVTTPS2PI
格式:CVTTPS2PI mm, xmm/m64
功能:低位的两个浮点数转变为整数,并且舍位
算法:
DEST[31-0] = (int) (SRC/m64[31-0]) ;
DEST[63-32] = (int) (SRC/m64[63-32]);
CVTTSS2SI
格式:CVTTSS2SI r32, xmm/ m32
功能:将最低位浮点数转换为整数,并舍位。
算法:
r32 = (INT) (SRC/m32[31-0]);
DIVPS
格式:DIVPS xmm1, xmm2/m128
功能:单精度数除法运算
算法:
DEST[31-0] = DEST[31-0] / (SRC/m128[31-0]) ;
DEST[63-32] = DEST[63-32] / (SRC/m128[63-32]) ;
DEST[95-64] = DEST[95-64] / (SRC/m128[95-64]) ;
DEST[127-96] = DEST[127-96] / (SRC/m128[127-96]);
DIVSS
格式:DIVSS xmm1, xmm2/m32
功能:低位单精度数除法
算法:
DEST[31-0] = DEST[31-0] / (SRC/m32[31-0]);
DEST[63-32] = DEST[63-32] ;
DEST[95-64] = DEST[95-64] ;
DEST[127-96] = DEST[127-96];
EMMS
格式:EMMS
功能:将浮点标识字置空
算法:
FPUTagWord <- FFFF
FXRSTOR
格式:FXRSTOR m512byte
功能:从m512byte中装入FP,MMX,以及SSE的状态
算法:
FP and MMX state and Streaming SIMD Extension state = m512byte;
FXSAVE
格式:FXSAVE m512byte
功能:向m512byte中存入FP,MMX,以及SSE的状态
算法:
m512byte = FP and MMX state and Streaming SIMD Extension state;
LDMXCSR
格式:LDMXCSR m32
功能:装入SSE的状态控制字
算法:
MXCSR = m32;
MAXPS
格式:MAXPS xmm1, xmm2/m128
功能:返回最大值
算法:
IF (DEST[31-0]=NaN) THEN
DEST[31-0] = SRC[31-0];
ELSEIF (SRC[31-0] = NaN) THEN
DEST[31-0] = SRC[31-0];
ELSEIF (DEST[31-0] > SRC/m128[31-0]) THEN
DEST[31-0] = DEST[31-0];
ELSE
DEST[31-0] = SRC/m128[31-0];
FI
IF (DEST[63-32]=NaN) THEN
DEST[63-32] = SRC[63-32];
ELSEIF (SRC[63-32] = NaN) THEN
DEST[63-32] = SRC[63-32];
ELSEIF (DEST[63-32] > SRC/m128[63-32]) THEN
DEST[63-32] = DEST[63-32];
ELSE
DEST[63-32] = SRC/m128[63-32];
FI
IF (DEST[95-64]=NaN) THEN
DEST[95-64] = SRC[95-64];
ELSEIF (SRC[95-64] = NaN) THEN
DEST[95-64] = SRC[95-64];
ELSEIF (DEST[95-64] > SRC/m128[95-64]) THEN
DEST[95-64] = DEST[95-64];
ELSE
DEST[95-64] = SRC/m128[95-64];
FI
IF (DEST[127-96]=NaN) THEN
DEST[127-96] = SRC[127-96];
ELSEIF (SRC[127-96] = NaN) THEN
DEST[127-96] = SRC[127-96];
ELSEIF (DEST[127-96] > SRC/m128[127-96]) THEN
DEST[127-96] = DEST[127-96];
ELSE
DEST[127-96] = SRC/m128[127-96];
FI
MAXSS
格式:MAXSS xmm1, xmm2/m32
功能:返回低位最大值
算法:同上面类似,区别在于只对DEST[31-0]进行操作
MINPS
格式:MINPS xmm1, xmm2/m128
功能:返回最小值
算法:略
MINSS
格式:MINSS xmm1, xmm2/m32
功能:返回低位最小值
算法:略
MOVAPS
格式:MOVAPS xmm1, xmm2/m128 或 MOVAPS xmm2/m128, xmm1
功能:对齐的数据传输指令
算法:
IF (destination = DEST) THEN
IF (SRC = m128)THEN (* load instruction *)
DEST[127-0] = m128;
ELSE(* move instruction *)
DEST[127=0] = SRC[127-0];
FI;
ELSE
IF (destination = m128)THEN (* store instruction *)
m128 = SRC[127-0];
ELSE(* move instruction *)
DEST[127-0] = SRC[127-0];
FI;
FI;
MOVHLPS
格式:MOVHLPS xmm1, xmm2
功能:高位的两个数传向低位
算法:
DEST[127-64] = DEST[127-64];
DEST[63-0] = SRC[127-64] ;
MOVHPS
格式:MOVHPS xmm, m64 或 MOVHPS m64, xmm
功能:高位数据传输指令
算法:
IF (destination = DEST) THEN(* load instruction *)
DEST[127-64] = m64;
DEST[31-0] = DEST[31-0];
DEST[63-32] = DEST[63-32];
ELSE (* store instruction *)
m64 = SRC[127-64];
FI;
MOVLPS
格式:MOVLPS xmm, m64 或 MOVLPS m64, xmm
功能:低位数据传输指令
算法:
IF (destination = DEST) THEN(* load instruction *)
DEST[63-0] = m64;
DEST[95-64] = DEST[95-64];
DEST[127-96] = DEST[127-96];
ELSE(* store instruction *)
m64 = DEST[63-0];
FI
MOVLHPS
格式:MOVLHPS xmm1, xmm2
功能:低位的两个数传向高位
算法:
DEST[127-64] = SRC[63-0];
DEST[63-0] = DEST[63-0];
MOVMSKPS
格式:MOVMSKPS r32, xmm
功能:掩码移入32位寄存器
算法:
r32[0] = SRC[31] ;
r32[1] = SRC[63] ;
r32[2] = SRC[95] ;
r32[3] = SRC[127];
r32[7-4] = 0X0 ;
r32[15-8] = 0X00 ;
r32[31-16] = 0X0000 ;
MOVNTPS
格式:MOVNTPS m128, xmm
功能:将数据直接存入内存,减小对缓存的压力
算法:
m128 = SRC;
MOVSS
格式:MOVSS xmm1, xmm2/m32 或 MOVSS xmm2/m32, xmm1
功能:最低位数据的传输指令
算法:
IF (destination = DEST) THEN
IF (SRC == m32) THEN(* load instruction *)
DEST[31-0] = m32;
DEST [63-32] = 0X00000000;
DEST [95-64] = 0X00000000;
DEST [127-96] = 0X00000000;
ELSE(* move instruction *)
DEST [31-0] = SRC[31-0];
DEST [63-32] = DEST [63-32];
DEST [95-64] = DEST [95-64];
DEST [127-96] = DEST [127-96];
FI
ELSE
IF (destination = m32) THEN(* store instruction *)
m32 = SRC[31-0];
ELSE (* move instruction *)
DEST [31-0] = SRC[31-0]
DEST [63-32] = DEST[63-32];
DEST [95-64] = DEST [95-64];
DEST [127-96] = DEST [127-96];
FI
FI
MOVUPS
格式:MOVUPS xmm1, xmm2/m128 或 MOVUPS xmm2/m128, xmm1
功能:非对齐数据的传输指令
算法:
IF (destination = xmm) THEN
IF (SRC = m128)THEN(* load instruction *)
DEST[127-0] = m128;
ELSE (* move instruction *)
DEST[127-0] = SRC[127-0];
FI
ELSE
IF (destination = m128) THEN(* store instruction *)
m128 = SRC[127-0];
ELSE (* move instruction *)
DEST[127-0] = SRC[127-0];
FI
FI
MULPS
格式:MULPS xmm1, xmm2/m128
功能:单精度数相乘
算法:
DEST[31-0] = DEST[31-0] * SRC/m128[31-0] ;
DEST[63-32] = DEST[63-32] * SRC/m128[63-32] ;
DEST[95-64] = DEST[95-64] * SRC/m128[95-64] ;
DEST[127-96] = DEST[127-96] * SRC/m128[127-96];
MULSS
格式:MULSS xmm1, xmm2/m32
功能:最低位的单精度数相乘
算法:
DEST[31-0] = DEST[31-0] * SRC/m32[31-0];
DEST[63-32] = DEST[63-32] ;
DEST[95-64] = DEST[95-64] ;
DEST[127-96] = DEST[127-96];
ORPS
格式:ORPS xmm1, xmm2/m128
功能:求或运算
算法:
DEST[127-0] |= SRC/m128[127-0];
RCPPS
格式:RCPPS xmm1, xmm2/m128
功能:求倒数的近似值
算法:
DEST[31-0] = APPROX (1.0/(SRC/m128[31-0])) ;
DEST[63-32] = APPROX (1.0/(SRC/m128[63-32])) ;
DEST[95-64] = APPROX (1.0/(SRC/m128[95-64])) ;
DEST[127-96] = APPROX (1.0/(SRC/m128[127-96]));
RCPSS
格式:RCPSS xmm1, xmm2/m32
功能:求最低位的倒数的近似值
算法:
DEST[31-0] = APPROX (1.0/(SRC/m32[31-0]));
DEST[63-32] = DEST[63-32] ;
DEST[95-64] = DEST[95-64] ;
DEST[127-96] = DEST[127-96];
RSQRTPS
格式:RSQRTPS xmm1, xmm2/m128
功能:求倒数平方根的近似值
算法:
DEST[31-0] = APPROX (1.0/SQRT(SRC/m128[31-0])) ;
DEST[63-32] = APPROX (1.0/SQRT(SRC/m128[63-32])) ;
DEST[95-64] = APPROX (1.0/SQRT(SRC/m128[95-64])) ;
DEST[127-96] = APPROX (1.0/SQRT(SRC/m128[127-96]));
RSQRTSS
格式:RSQRTSS xmm1, xmm2/m32
功能:求最低位倒数平方根的近似值
算法:
DEST[31-0] = APPROX (1.0/SQRT(SRC/m32[31-0]));
DEST[63-32] = DEST[63-32] ;
DEST[95-64] = DEST[95-64] ;
DEST[127-96] = DEST[127-96];
SHUFPS
格式:SHUFPS xmm1, xmm2/m128, imm8
功能:打乱顺序
算法:
FP_SELECT = (imm8 >> 0) AND 0X3;
IF (FP_SELECT = 0) THEN
DEST[31-0] = DEST[31-0];
ELSEIF (FP_SELECT = 1) THEN
DEST[31-0] = DEST[63-32];
ELSEIF (FP_SELECT = 2) THEN
DEST[31-0] = DEST[95-64];
ELSE
DEST[31-0] = DEST[127-96];
FI
FP_SELECT = (imm8 >> 2) AND 0X3;
IF (FP_SELECT = 0) THEN
DEST[63-32] = DEST[31-0];
ELSEIF (FP_SELECT = 1) THEN
DEST[63-32] = DEST[63-32];
ELSEIF (FP_SELECT = 2) THEN
DEST[63-32] = DEST[95-64];
ELSE
DEST[63-32] = DEST[127-96];
FI
FP_SELECT = (imm8 >> 4) AND 0X3;
IF (FP_SELECT = 0) THEN
DEST[95-64] = SRC/m128[31-0];
ELSEIF (FP_SELECT = 1) THEN
DEST[95-64] = SRC/m128 [63-32];
ELSEIF (FP_SELECT = 2) THEN
DEST[95-64] = SRC/m128 [95-64];
ELSE
DEST[95-64] = SRC/m128 [127-96];
FI
FP_SELECT = (imm8 >> 6) AND 0X3;
IF (FP_SELECT = 0) THEN
DEST[127-96] = SRC/m128 [31-0];
ELSEIF (FP_SELECT = 1) THEN
DEST[127-96] = SRC/m128 [63-32];
ELSEIF (FP_SELECT = 2) THEN
DEST[127-96] = SRC/m128 [95-64];
ELSE
DEST[127-96] = SRC/m128 [127-96];
FI
SQRTPS
格式:SQRTPS xmm1, xmm2/m128
功能:求平方根
算法:
DEST[31-0] = SQRT (SRC/m128[31-0] );
DEST[63-32] = SQRT (SRC/m128[63-32]);
DEST[95-64] = SQRT (SRC/m128[95-64]);
DEST[127-96] = SQRT (SRC/m128[127-96]);
SQRTSS
格式:SQRTSS xmm1, xmm2/m32
功能:最低位数求平方根
算法:
DEST[31-0] = SQRT (SRC/m32[31-0]);
DEST[63-32] = DEST[63-32];
DEST[95-64] = DEST[95-64];
DEST[127-96] = DEST[127-96];
STMXCSR
格式:STMXCSR m32
功能:存储SSE控制字
算法:
m32 = MXCSR;
SUBPS
格式:SUBPS xmm1, xmm2/m128
功能:单精度数的减法运算
算法:
DEST[31-0] = DEST[31-0] - SRC/m128[31-0] ;
DEST[63-32] = DEST[63-32] - SRC/m128[63-32];
DEST[95-64] = DEST[95-64] - SRC/m128[95-64];
DEST[127-96] = DEST[127-96] - SRC/m128[127-96];
SUBSS
格式:SUBSS xmm1, xmm2/m32
功能:最低位数相减
算法:
DEST[31-0] = DEST[31-0] - SRC/m32[31-0];
DEST[63-32] = DEST[63-32];
DEST[95-64] = DEST[95-64];
DEST[127-96] = DEST[127-96];
UCOMISS
格式:UCOMISS xmm1, xmm2/m32
功能:比较低位数并且设置标志位
算法:
OF = 0;
SF = 0;
AF = 0;
IF ((DEST[31-0] UNORD SRC/m32[31-0]) = TRUE) THEN
ZF = 1;
PF = 1;
CF = 1;
ELSEIF ((DEST[31-0] GTRTHAN SRC/m32[31-0]) = TRUE)THEN
ZF = 0;
PF = 0;
CF = 0;
ELSEIF ((DEST[31-0] LESSTHAN SRC/m32[31-0]) = TRUE THEN
ZF = 0;
PF = 0;
CF = 1;
ELSE
ZF = 1;
PF = 0;
CF = 0;
FI
UNPCKHPS
格式:UNPCKHPS xmm1, xmm2/m128
功能:高位两数交替传输
算法:
DEST[31-0] = DEST[95-64];
DEST[63-32] = SRC/m128[95-64];
DEST[95-64] = DEST[127-96];
DEST[127-96] = SRC/m128[127-96];
UNPCKLPS
格式:UNPCKLPS xmm1, xmm2/m128
功能:低位两数交替传输
算法:
DEST[31-0] = DEST[31-0];
DEST[63-32] = SRC/m128[31-0];
DEST[95-64] = DEST[63-32];
DEST[127-96] = SRC/m128[63-32];
XORPS
格式:XORPS xmm1, xmm2/m128
功能:异或运算
算法:
DEST[127-0] = DEST/m128[127-0] XOR SRC/m128[127-0]