SSE を利用するために、(Visual Studio 2012 C++ コードで) インライン アセンブラーを実装しようとしています。1e9回の7つの数字を追加したいので、RAMからCPUのxmm0からxmm6レジスタに配置しました。次のコードを使用して、Visual Studio 2012 でインライン アセンブリを使用すると、次のようになります。
C++ コード:
for(int i=0;i<count;i++)
resVal+=val1+val2+val3+val4+val5+val6+val7;
私のASMコード:
int count=1000000000;
double resVal=0.0;
//placing values to register
__asm{
movsd xmm0,val1;placing var1 in xmm0 register
movsd xmm1,val2
movsd xmm2,val3
movsd xmm3,val4
movsd xmm4,val5
movsd xmm5,val6
movsd xmm6,val7
pxor xmm7,xmm7;//turns xmm7 to zero
}
for(int i=0;i<count;i++)
{
__asm
{
addsd xmm7,xmm0;//+=var1
addsd xmm7,xmm1;//+=var2
addsd xmm7,xmm2;
addsd xmm7,xmm3;
addsd xmm7,xmm4;
addsd xmm7,xmm5;
addsd xmm7,xmm6;//+=var7
}
}
__asm
{
movsd resVal,xmm7;//placing xmm7 into resVal
}
これは、コード 'resVal+=val1+val2+val3+val4+val5+val6+val7' の C++ コンパイラから逆アセンブルされたコードです。
movsd xmm0,mmword ptr [val1]
addsd xmm0,mmword ptr [val2]
addsd xmm0,mmword ptr [val3]
addsd xmm0,mmword ptr [val4]
addsd xmm0,mmword ptr [val5]
addsd xmm0,mmword ptr [val6]
addsd xmm0,mmword ptr [val7]
addsd xmm0,mmword ptr [resVal]
movsd mmword ptr [resVal],xmm0
ご覧のとおり、コンパイラは xmm0 レジスタを 1 つだけ使用し、それ以外の場合は RAM から値をフェッチしています。
両方のコード (私の ASM コードと C++ コード) の答えは同じですが、C++ コードの実行時間は私の asm コードの約半分です!
CPUレジスタについて読んだところ、それらを使用する方がメモリよりもはるかに高速です。この比率が正しいとは思えません。asm バージョンの C++ コードのパフォーマンスが低いのはなぜですか?