数学計算を行うための SSE 最適化コードの一部では、単一の movups 命令の代わりに movlps 命令と movhps 命令の組み合わせを使用して、整列されていないデータを転送することがわかりました。理由がわからないので、自分で試してみました。以下の疑似コードです。
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 バージョンの場合、結果は約 50ms です。
movlps、movhps バージョンの場合、結果は約 46ms です。
また、構造体に __declspec(align(16)) 記述子を使用し、_aligned_malloc() によって割り当てられたデータ整列バージョンも試しました。結果は約 34ms です。
movlps と movhps を組み合わせた方が速いのはなぜですか? movup の代わりに movlps と movhps を使用した方がよいということですか?