4

4つのdoubleを含むAVXレジスタがあり、その逆を別のレジスタに格納したい場合、単一の組み込みコマンドでこれを実行できますか?

例:SSEレジスタに4つのフロートがある場合、次を使用できます。

_mm_shuffle_ps(A,A,_MM_SHUFFLE(0,1,2,3));

多分、これを使用してこれを行うことはできます_mm256_permute2f128_pd()か?上記の組み込みを使用して、個々のダブルに対処することはできないと思います。

4

2 に答える 2

11

これを行うには、実際には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
于 2012-11-16T19:42:17.350 に答える
4

より細かい128ビットのレーンクロッシングシャッフルのサポートは、AVX2の新機能です。

_mm256_permute4x64_pd(vec, _MM_SHUFFLE(0,1,2,3));  // i.e. 0b00011011

VPERMPD ymm1, ymm2/m256, imm8VPERM2F128Intel CPU上の他のレーンクロッシングシャッフル(など)と同じスループットとレイテンシで実行されます。本質的なファインダーでも。

AMD Zen1(およびExcavator)では、vpermpd2入力よりも高速です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) 、または関数のさらに別のバージョンを作成します。

于 2016-03-13T09:32:54.327 に答える