这次将介绍SSE扩展指令集,以及矩阵乘法的优化,不喜汇编者请发送WM_CLOSE消息!!
闲话就不说了,SSE指令的历史到处都是,主要说说我对指令集的原理、作用和用法的理解。
SSE指令集的最大有点就是能够 4个float并行运算,与其说这恰好符合图形算法,到不如说就是为图形编程设计的。比如说,两个向量相加,x1+x2, y1+y2, z1+z2, w1+w2。用了4条加法指令,不如来一条省事。这就是SSE能为我们做的。这里要介绍8个寄存器:xmm0, xmm1, xmm2...xmm6, xmm7,这些寄存器都是128位的,每个寄存器都可以存放4个float,所以,x1, y1, z1, w1这4个float型可以放在xmm0中,而x2, y2, z2, w2可以放在xmm1中,于是 xmm0 += xmm1,结果就保存在xmm0寄存器了!下面是代码:
struct Vector
{
float x, y, z, w;
void Add(const Vector* pIn)
{
_asm
{
mov eax, pIn; // 这里其实应该是 mov eax, dword ptr[pIn];
mov ecx, this;
movups xmm0, [ecx]; // 把this的xyzw放入xmm0
movups xmm1, [eax]; // 把pIn的xyzw放入xmm1
addps xmm0, xmm1; // xmm0 += xmm1
movups [ecx], xmm0; // 把xmm0的值给this
mov [ecx+12], 3F800000h // 别忘了给w = 1.0f
}
}
}
其实也就这么简单,movups是把内存中的向量放入寄存器,或者把寄存器中的向量放回内存,总之是一次移动128个位的一条指令,这个指令比普通的MOV指令要慢70%左右,比浮点乘法要慢的多了,大量的时间花在了movups上。所以说,简单的算法不值得去用SSE指令。这个向量加法指令很可能会比下面的算法更慢:
void Add(const Vector* pIn)
{
x += pIn->x;
y += pIn->y;
z