インテル® AVX2 によるプログラミング置換

特集

この記事は、インテル® デベロッパー・ゾーンに公開されている「Programming using AVX2. Permutations.」(https://software.intel.com/en-us/blogs/2015/01/13/programming-using-avx2-permutations) の日本語参考訳です。


私たちは、インテル® アドバンスト・ベクトル・エクステンション 2 (インテル® AVX2) ではベクトル長がインテル® ストリーミング SIMD 拡張命令 4.2 (インテル® SSE4.2) の 128 ビットから 256 ビットに拡張されたことを知っています。パックド add、sub、mul などの基本命令は、これにより最大 2 倍のパフォーマンスの優位性がありますが (ベクトル長が 2 倍に広がったことにより)、いくつかの命令のパフォーマンス・ゲインはそれほど明確ではありません。この記事では、そのような命令の置換について説明します。

簡単に言うと、インテル® AVX2 置換のセットは、上位と下位の 128 ビットにそれぞれ個別に適用されます。これらの命令には vpalignr、すべての vpack 命令、すべての vpunpck 命令、そして vpshufb 命令があります。

例を示します (ymm は 256 ビット・レジスター):

vpalignr ymm0, ymm2, ymm1, $12

は、次のようになります:

palignr ymm0.lo, ymm2.lo, ymm1.lo, $12
palignr ymm0.hi, ymm2.hi, ymm1.hi, $12

ここで、ymm.lo ymm の下位 128 ビットで、ymm.hiymm の上位 128 ビットです。

ここで、”vpalignr” を “palignr” に置き換え、”ymm” を “xmm” に換えただけでは正しい結果は得られません (暗青色が期待される結果):

そのため、最初の操作に “vperm2i128” を使用して、正しい結果を取得します:

ここで 2 つの命令が必要になります: “vperm2i128” と “vpalignr” は、”palignr” を 256 ビットに拡張します。

次に、”vpack”、”vpunpck” そして “vpshufb” 向けのスキームを示します。

VPACK

“*” はゼロであると考えます。この例では、クアッドワードを操作します (ベクトルを視覚的に短くするため)。vpack 命令はワードとダブルワードのみを操作しますが、クアッドワードでもスキームは同じです。

ここで “vpermq” は、最終的なベクトルを取得するために使用されます。そのため、2 つの命令が必要になります。

VPUNPCKL (下位をアンパック)

“vperm2i128” を使用して ymm0 と ymm1 から、上位と下位の値を取得できることは、私たちにとって幸いです。下位を取得する:

punpck[l,h] をそれぞれ拡張するには 3 つの命令が必要で、両者では 4 命令で済みます。

VPSHUFB

ワード (16 ビット) で構成される 256 ビットのベクトルがあります:

そして、最終的に次のベクトルを取得します:

その後置換を完了するため、2 つの “vpshufb”、”vpermq” および “vpor” 命令が必要です。最初に要素をシャッフルし、他のベクトルへ移動します (上位から下位、下位から上位)。ここでは、”F” と “0” です。他の要素はゼロ “*” で埋められます (vpshufb 命令は、マスクが -128 であれば、対応する位置にゼロを埋めます)。ここでは、ベクトルの 128 ビットだけを操作できることを忘れないでください。

次のシャッフルで残りの要素を処理します。準備ができている位置はゼロ “*” が埋められます:

最後に 2 つのベクトルを 1 つに結合します:

コンパイラーの最適化に関する詳細は、最適化に関する注意事項を参照してください

タイトルとURLをコピーしました