为什么使用SSE指令没有提升性能-附代码
最近在做一个程序,中间有一段大量的计算,最核心的一段主要就是乘加操作,原来的C++代码如下:
struct TStatxSimpleRecord
{
float Mean;
float Stdevp;
};
for(i=minx; i<=maxx;i++)
{
float disx2 = square(i*fstepx - x); //squre是自己写的平方函数
for(j=miny; j<maxy; j++)
{
float disy2 = square(j*fstepy - y);
//下面的Exptor.Exp是自己做的快速指数函数,其实就是查表,跟本帖关系不大
float weight = Exptor.Exp((disx2+disy2)*lamda2);
TStatxSimpleRecord * pcd = pxsr[i][j];
//下面代码本来可以用一个循环的,为了提升性能,已经做了循环展开
pcd[0].Mean += weight*gain[0]; //gain和下面的g2都是事先计算得到的一个4个浮点数的数组
pcd[1].Mean += weight*gain[1]; //其中g2[i] = gain[i]*gain[i]
pcd[2].Mean += weight*gain[2];
pcd[3].Mean += weight*gain[3];
pcd[0].Stdevp += weight*g2[0];
pcd[1].Stdevp += weight*g2[1];
pcd[2].Stdevp += weight*g2[2];
pcd[3].Stdevp += weight*g2[3];
}
}
因为上面这两层循环是在一个需要执行200万次的大循环里面,所以对性能影响非常大,现在程序执行一次大约需要12分钟。考虑到上面的数据刚好都是4个浮点数,所以希望通过SSE指令加速一下。下面是用SSE改写的代码:
__asm {
mov eax, t1
movups xmm0, [eax] //复制gain到xmm0
movaps xmm1, xmm0 //复制xmm0到xmm1
mulps xmm1, xmm1 //xmm1平方,得到g2
}
for(i=minx; i<=maxx;i++)
{
float disx2 = square(i*fstepx - x);
for(j=miny; j<maxy; j++)
{
float disy2 = square(j*fstepy - y);
float weight = Exptor.Exp((disx2+disy2)*lamda2);
pdencity[i][j] += weight;
//下面的TVCT是一个临时的结构,struct TVCT{float x; float y; float z; float w;}
//使用这个结构是因为我不知道其他把下面数组内容拷贝到SSE寄存器的方法,
//有人知道的话也请告诉一声,一样有分
TVCT & t2 = *(TVCT *)(pmean[i][j]);
TVCT & t3 = *(TVCT *)(pstd[i][j]);
__asm
{
movss xmm2, weight
shufps xmm2, xmm2, 0x00 //expand weight to 4
mov eax, t2
movaps xmm3, [eax] //mean
movaps xmm4, xmm0 //load gain
mulps xmm4, xmm2 //weight * gain
addps xmm3, xmm4 //mean += weight*gain
movaps [eax], xmm3
mov eax, t3
movaps xmm5, [eax] //std
movaps xmm6, xmm1 //load gain*gain
mulps xmm6, xmm2 //weight*gain*gain
addps xmm5, xmm6
movaps [eax], xmm5
}
}
}
这段代码运行的结果是正确的,与原来的代码得到的结果完全一样(数据16字节对齐的问题我已经注意到了)。但性能出人意料,一点都没有提升(我原来预计有3倍左右的提升),当然也没有降低。
我检查了汇编结果,确实已经使用了SSE指令,寄存器xmm的内容也是正常的。
数据总线的瓶颈我也考虑过,SSE执行的顺序大致安排使得计算跟数据操作分开。
为避免窗口程序的影响,我另外做了一个控制台程序,性能表现没有区别。
现在我想不出还有什7么理由导致性能无法提升,请高手指点。
我使用的CPU:Intel Core Duo T5750,按手册已经CPUID的测试,是支持SSE指令的。
编译器:C++ Builder 2009
OS:Windows Vista Home Basic