2012-04-25 4 views
6

。私が見ていることは、SSE命令を実行するために必要なロードとストアが頻繁に発生することは、ベクトル計算のために得られる利得を無効にすることです。ですから、誰かが私にSSEコードの例を教えてもらえますか?は、通常の手順をアウトパフォームするx86-64の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_i32poに割り当てますか?

+1

、比。 – Mysticial

+2

ええ、あなたは間違いなくそのような '_mm_set_epi32()'を使いたくありません。 '_mm_load_si128()'を使用してください。また、データを整列できない場合は、パフォーマンスペナルティで '_mm_loadu_si128()'を使用することができます。 – Mysticial

+1

データを整列しますか?それどういう意味? – pythonic

答えて

10

答えにコメントを要約:

あなたは基本的に、ほとんどの最初のタイマーをキャッチし、同じ罠に陥っています。基本的にあなたの例には2つの問題があります:

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

_mm_set_epi32()は非常に高価で固有のものです。使用するのは便利ですが、1つの命令にはコンパイルされません。一部のコンパイラ(VS2010など)は、_mm_set_epi32()を使用すると、パフォーマンスの低いコードを生成することがあります。あなたは、メモリの連続ブロックをロードしているので、

代わりに、あなたは_mm_load_si128()を使用する必要があります。そのためには、ポインタが16バイトに揃えられている必要があります。この調整を保証できない場合は、_mm_loadu_si128()を使用することができますが、パフォーマンス上のペナルティを伴います。理想的には、_mm_loadu_si128()を使用する必要がないようにデータを正しく整列させる必要があります。


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

ループ展開は、あなたが長い依存性チェーンを持つ大規模なループ体を持っているときのパフォーマンスを最大化することがしばしば必要です。


スピードアップを成功させるためにSSEをうまく使用していると思われるいくつかの例があります。

関連する問題