7

x86-64のSSE命令(ベクトル命令)は、通常の命令よりもどこで優れていますか。私が見ているのは、SSE命令を実行するために必要な頻繁なロードとストアが、ベクトル計算によるゲインを無効にしているためです。それで、誰かが私に通常のコードよりもパフォーマンスが良いSSEコードの例を教えてもらえますか?

このように、各パラメータを個別に渡しているためかもしれません...

__m128i a = _mm_set_epi32(pa[0], pa[1], pa[2], pa[3]);
__m128i b = _mm_set_epi32(pb[0], pb[1], pb[2], pb[3]);
__m128i res = _mm_add_epi32(a, b);

for( i = 0; i < 4; i++ )
 po[i] = res.m128i_i32[i];

4つの整数すべてを一度に渡す方法はありませんか?つまり、128バイト全体を一度に渡すというpaことですか?そして、一度に割り当てres.m128i_i32ますpoか?

4

1 に答える 1

10

コメントを答えに要約する:

あなたは基本的に、ほとんどの初めての人を捕まえるのと同じ罠に陥っています。基本的に、あなたの例には2つの問題があります。

  1. あなたは誤用して_mm_set_epi32()います。
  2. 計算/ロードストアの比率が非常に低くなっています。(あなたの例では1から3)

_mm_set_epi32()非常に高価な本質です。使用するのは便利ですが、単一の命令にコンパイルされません。一部のコンパイラ(VS2010など)は、を使用すると非常にパフォーマンスの低いコードを生成する可能性があります_mm_set_epi32()

代わりに、メモリの連続したブロックをロードしているので、を使用する必要があります_mm_load_si128()。そのためには、ポインタが16バイトに揃えられている必要があります。この配置を保証できない場合は、使用できます_mm_loadu_si128()が、パフォーマンスが低下します。理想的には、を使用する必要がないように、データを適切に調整する必要があります_mm_loadu_si128()


SSEを使用すると真に効率的であり、計算/ロードストアの比率を最大化することもできます。私が狙っているターゲットは、メモリアクセスごとに3〜4個の算術命令です。これはかなり高い比率です。通常、コードをリファクタリングするか、アルゴリズムを再設計してコードを増やす必要があります。データのパスを組み合わせるのが一般的なアプローチです。

依存関係のチェーンが長い大きなループ本体がある場合、パフォーマンスを最大化するには、ループの展開が必要になることがよくあります。


スピードアップを達成するためにSSEをうまく使用するSO質問のいくつかの例。

于 2012-04-25T10:48:12.373 に答える