我发现在一些用于进行数学计算的 SSE 优化代码中,它们使用 movlps 和 movhps 指令的组合而不是单个 movups 指令来传输未对齐的数据。不知道为什么,我自己试了一下,是下面的伪代码:
struct Vec4
{
float f[4];
};
const size_t nSize = sizeof(Vec4) * 100;
Vec4* pA = (Vec4*)malloc( nSize );
Vec4* pB = (Vec4*)malloc( nSize );
Vec4* pR = (Vec4*)malloc( nSize );
...Some data initialization code here
...Records current time by QueryPerformanceCounter()
for( int i=0; i<100000, ++i )
{
for( int j=0; j<100; ++j )
{
Vec4* a = &pA[i];
Vec4* b = &pB[i];
Vec4* r = &pR[i];
__asm
{
mov eax, a
mov ecx, b
mov edx, r
...option 1:
movups xmm0, [eax]
movups xmm1, [ecx]
mulps xmm0, xmm1
movups [edx], xmm0
...option 2:
movlps xmm0, [eax]
movhps xmm0, [eax+8]
movlps xmm1, [ecx]
movhps xmm1, [ecx+8]
mulps xmm0, xmm1
movlps [edx], xmm0
movhps [edx+8], xmm0
}
}
}
...Calculates passed time
free( pA );
free( pB );
free( pR );
我多次运行代码并计算了它们的平均耗时。
对于 movups 版本,结果大约是 50 毫秒。
对于movlps,movhps版本,结果大约是46ms。
而且我还尝试了一个数据对齐版本,在结构上使用 __declspec(align(16)) 描述符,并由 _aligned_malloc() 分配,结果大约是 34 毫秒。
为什么 movlps 和 movhps 的组合更快?这是否意味着我们最好使用 movlps 和 movhps 而不是 movups?