4つのdoubleを含むAVXレジスタがあり、その逆を別のレジスタに格納したい場合、単一の組み込みコマンドでこれを実行できますか?
例:SSEレジスタに4つのフロートがある場合、次を使用できます。
_mm_shuffle_ps(A,A,_MM_SHUFFLE(0,1,2,3));
多分、これを使用してこれを行うことはできます_mm256_permute2f128_pd()
か?上記の組み込みを使用して、個々のダブルに対処することはできないと思います。
4つのdoubleを含むAVXレジスタがあり、その逆を別のレジスタに格納したい場合、単一の組み込みコマンドでこれを実行できますか?
例:SSEレジスタに4つのフロートがある場合、次を使用できます。
_mm_shuffle_ps(A,A,_MM_SHUFFLE(0,1,2,3));
多分、これを使用してこれを行うことはできます_mm256_permute2f128_pd()
か?上記の組み込みを使用して、個々のダブルに対処することはできないと思います。
これを行うには、実際には2つの並べ替えが必要です。
_mm256_permute2f128_pd()
128ビットチャンクでのみ並べ替えます。_mm256_permute_pd()
128ビットの境界を越えて順列しません。したがって、両方を使用する必要があります。
inline __m256d reverse(__m256d x){
x = _mm256_permute2f128_pd(x,x,1);
x = _mm256_permute_pd(x,5);
return x;
}
テスト:
int main(){
__m256d x = _mm256_set_pd(13,12,11,10);
cout << x.m256d_f64[0] << " " << x.m256d_f64[1] << " " << x.m256d_f64[2] << " " << x.m256d_f64[3] << endl;
x = reverse(x);
cout << x.m256d_f64[0] << " " << x.m256d_f64[1] << " " << x.m256d_f64[2] << " " << x.m256d_f64[3] << endl;
}
出力:
10 11 12 13
13 12 11 10
より細かい128ビットのレーンクロッシングシャッフルのサポートは、AVX2の新機能です。
_mm256_permute4x64_pd(vec, _MM_SHUFFLE(0,1,2,3)); // i.e. 0b00011011
VPERMPD ymm1, ymm2/m256, imm8
VPERM2F128
Intel CPU上の他のレーンクロッシングシャッフル(など)と同じスループットとレイテンシで実行されます。本質的なファインダーでも。
AMD Zen1(およびExcavator)では、vpermpd
2入力よりも高速ですvperm2f128
。それらのベクトルALUは、内部的には128ビット幅しかありません。256ビットのベクトル命令は少なくとも2uopsにデコードされますが、レーン横断操作、特に合計4つのレーンのいずれかを読み取ることができる操作にはさらに時間がかかります。(残念ながら、デコーダーはvperm2f128のuopsを選択するときに直接ビットを確認するだけではありません)。手動vextractf128
/vinsertf128
はブルドーザーファミリーやZen1よりも優れvperm2f128
ていますが、それ以外の場所ではかなり悪いでしょう。https://uops.info/。vpermpd
掘削機/Zen1では3uopsであるのに対し、レーン内で少なくとも4 uopsで、半分をvextracti128
/で交換するのが最適だと思いますvinsert128
。
FMA3を搭載しているがAVX2を搭載していないCPUがいくつかあります(AMD PiledriverやSteamrollerなど)。Intelでは、AVX2とFMAはどちらもHaswellの新機能です。AMD Bulldozerファミリーは廃止されましたが、家庭用コンピューターにはまだ存在しているため、機能がAVX1 + FMAを利用している場合でも、AVX2を要求し、それらの少数のCPUをさらに悪いものにフォールバックさせるオプションがあります(たとえば、FMAのないAVX1) 、または関数のさらに別のバージョンを作成します。