2016-08-31 2 views
0

一部のCコードでAVX2命令を使用しています。ソースベースのインデックスからデスティネーションベースのインデックスへの変換

VPERMD命令はidxに基づいaを置換することによって、2つの8整数ベクトルaidxを取り、第三のいずれかを生成する、dst。これはdst[i] = a[idx[i]] for i in 0..7に相当します。このソースは、ソースに基づいてインデックス付けされているため、このソースをベースとしています。

ただし、計算されたインデックスは宛先ベースの形式になっています。配列を設定するのは当然ですが、これはdst[idx[i]] = a[i] for i in 0..7に相当します。

ソースベースのフォームから宛先ベースのフォームに変換するにはどうすればよいですか?例のテストケースがある:この変換のために

{2 1 0 5 3 4 6 7} source-based form. 
{2 1 0 4 5 3 6 7} destination-based equivalent 

、私はYMMレジスタに滞在していますので、それは宛先ベースのソリューションが動作しないことを意味します。個別に挿入する場合でも、定数インデックスのみで動作するため、設定することはできません。

+1

これはまさに古典的な "順列逆転"、dst [src [i]] = iの – harold

+0

です。しかし、あなたのコードでは、宛先ベースの方法で設定する機能が必要です。私はAVX2レジスタで動作しているので私はそれをすることはできません。私はあなたが言うように、ほぼ正確にそれを行うCコードを持っていますが、私はあなたが示唆するように、宛先ベースの並べ替えを行うことができずにインデックスを変換することができる必要があります。 – eyepatch

+0

あなたの 'a [i] = a [idx [i]]は、VPERMDの操作を正しく記述しませんでした。なぜなら、' a'への変更は 'a [idx [ i]] 'に置き換えます。例えばidx [0] = 0でなければ、元の 'a [0]'はすぐに破棄されます。私はあなたの例は、そのバグを修正するために私の編集後にはまだ正気であると思う(またはその時間全体の行動を仮定していた)。 –

答えて

2

最初にソースベースのインデックスを計算するようにコードを変更することはできないと思いますか?私はあなたがx86 SIMDでできることは考えていません.DSTベースのインデックスを取るAVX512散布命令以外のものです。

ベクトルのメモリへの格納、反転、および再ロードは実際には最適です。 (または、整数レジスタに直接転送するのではなく、メモリからではなく、vextracti128/packusdwの後に、ベクトルから整数の2つの64ビット転送(movqとpextrq)が必要です。

しかし、とにかくそれらをインデックスとして使用して、メモリ内の配列にカウンタを格納し、それをベクトルとしてリロードします。これはまだ遅くて醜いですし、店舗運送の失敗の遅れがあります。だから、インデックスベースのコードを変更してソースベースのシャッフルベクタを生成することは、おそらく価値があります。

関連する問題