5

数学計算を行うための 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 を使用した方がよいということですか?

4

2 に答える 2

6

この世代 (K8) のアスロンには、64 ビット幅の ALU ユニットしかありません。したがって、すべての 128 ビット SSE 命令を 2 つの 64 ビット命令に分割する必要があり、一部の命令ではオーバーヘッドが発生します。

このタイプのプロセッサでは、通常、同等の MMX コードと比較して、SSE を使用してもスピードアップは見られません。

Agner Fogの引用: The microarchitecture of Intel, AMD and VIA CPUs: アセンブリ プログラマーおよびコンパイラー メーカー向けの最適化ガイド:

12.9 64 ビット命令と 128 ビット命令

K10 で 128 ビット命令を使用することは大きな利点ですが、K8 では各 128 ビット命令が 2 つの 64 ビット マクロ操作に分割されるため、K8 では使用しません。

128 ビット メモリ書き込み命令は、K10 では 2 つの 64 ビット マクロ操作として処理されますが、128 ビット メモリ読み取りは、K10 では 1 つのマクロ操作 (K8 では 2) で実行されます。

128 ビットのメモリ読み取り命令は、K8 では FMISC ユニットのみを使用しますが、K10 では 3 つのユニットすべてを使用します。したがって、データのブロックをあるメモリ位置から別のメモリ位置に移動するためだけに XMM レジスタを使用することは、k8 では有利ではありませんが、K10 では有利です。

于 2012-11-23T08:33:21.560 に答える
1

movups は、位置合わせされていないデータで機能します。movlps、movhps は、アラインされたデータでのみ機能します。確かに movlps、movhps の方が高速です。時間の計算と比較には、ms ではなく rdtsc を使用することをお勧めします。

于 2012-11-23T08:12:59.887 に答える