2013-04-24 17 views
11

ロード命令などVPGATHERDDなどが集まっているAVX2の組み込み関数のドキュメントを見て:ドキュメントから私には明らかではないが、何AVX2は、命令を集める - ロードアドレス計算

__m128i _mm_i32gather_epi32 (int const * base, __m128i index, const int scale); 

が算出したロードアドレスがあるされているかどうかを

load_addr = base + index[i] * scale;    // (1) element addressing ? 

か:要素アドレスまたはバイトアドレス、すなわち要素iのためのロードアドレスであります: Intel docsから

load_addr = (char *)base + index[i] * scale;  // (2) byte addressing ? 

それはあるかもしれないように、それは(2)に見えますが、これは集まっ負荷の最小要素サイズが32ビットであることを考えるとあまり意味がありません - なぜあなたはずれたアドレスからロードしたいと思います(すなわち、スケールを使用< 4)?

答えて

8

ギャザーの指示にアラインメントの要件はありません。したがって、バイトアドレッシングを許可しないようにすることはあまりにも制限的です。

その他の理由は一貫性です。本当に関しては

VPGATHERDD ymm0, [rcx + ymm2 * 2], ymm3 

を:VPGATHERDDこのMOV命令の単なるベクトル化変種であるので、我々はVSIBと異なるものが取り組む期待すべきではない

MOV eax, [rcx + rdx * 2] 

:SIBは明らかに我々に対処してバイトアドレスを持っていますバイトアドレッシングでは、各ピクセルが3バイトで整列された24ビットのカラーイメージを使用できます。 VSIBの "scale"フィールドが "1"で、VPGATHERDDバイトのアドレッシングを使用する場合に限り、単一のVPGATHERDD命令で8ピクセルをロードできます。

+1

OK - ありがとう - 私はそれが意味をなさないと思うし、ドキュメントと一貫している。あなたはロードに関する良い点を立てます。 3バイトのピクセル値。 –

4

インテルのAVX programming reference document available hereの記述で判断すると、ギャザー命令でバイトアドレッシングが使用されているようです。具体的には、(ページ389)VPGATHERDD命令の記述から、以下の引用を参照してください。

DISP: optional 1, 2, 4 byte displacement; 
DATA_ADDR = BASE_ADDR + (SignExtend(VINDEX[i+31:i])*SCALE + DISP; 

あなたは1/2/4バイトの変位を使用することができますので、私はその全体的なメモリ・アドレスを引き受けますバイトアドレスです。これは一般的なアプリケーションではありませんが、ミスアラインメントされたアドレスから32ビットまたは64ビットの値を読み取ることが必要な場合があります。これは、ARMのようなものと比べると、x86アーキテクチャーに関するより柔軟なものの1つです。必要に応じて、CPUの例外をトリガするのではなく、他のものと同じように、不整合なアクセスを実行する柔軟性があります。

+1

ARMV6 –

+0

ご迷惑をおかけして、訂正ありがとうございます。私のARMの経験は幾分古いものになっています。 –

1

なぜ調整されていないアドレスからロードしたいのですか(スケール< 4を使用)。

要素のサイズが<の場合、整列していない負荷だけがユースケースではありません。スケーリングされていないバイトオフセットであるインデックスを持つだけかもしれません。または、構造体へのポインタの配列のループをベクトル化することを検討してください。ゼロのベース "アドレス"または構造体への小さな整数のオフセットで集めることができます。

このユースケースをサポートすることは、インテルがこれをサポートするasm命令を設計する理由の1つです。なぜなら、ギャザーはコンパイラがより多くのコードを自動ベクトル化するのに役立つからです。また、VSIBバイトがマシンコードエンコーディングでSIBに非常に近いことは当然のことですが、スケールファクタに事前バイアスをかけることで、スケール= 4,8,16,32(または8 、16,32,64(qword集約用))を2ビットのスケール・フィールドで置き換えます。

要素のサイズより大きなスケールファクタは、多くの場合には明らかに有用ではなく、収集前に単一の左シフト命令でエミュレートするのが容易です。しかし焼き付けスケールファクタを回避することは不可能なので、スケーリングされていないインデックスを許可すると、より柔軟な設計選択が可能になります。


その他の使用例:16ビット要素を収集する。 32ビットのギャザーを使用し、ギャザーの後に各要素の上半分をマスクします。 (あるいはちょうどゴミを入れたままにしておきます)。これは、あなたのインデックスが奇数(2のスケールファクタ)であると、ミスアライメントされた負荷になるため、真の16ビットギャザーとは異なり、4Kの境界を横切ると遅くなる可能性があります。

解凍関数の一部としてギャザーを使用すると、デコード後にバッファへのオフセットのベクトルがあり、任意の4バイトまたは8バイトのデータウィンドウが必要になる場合もあります。

関連する問題