4

次の AVX 操作を行う必要があります。

__m256 perm, func;
__m256 in = _mm256_load_ps(inPtr+x);
__m256 acc = _mm256_setzero_ps();

perm = _mm256_shuffle_ps(in, in, _MM_SHUFFLE(3,2,1,0));
func = _mm256_load_ps(fPtr+0);
acc = _mm256_add_ps(acc, _mm256_mul_ps(perm, func));

perm = _mm256_shuffle_ps(in, in, _MM_SHUFFLE(2,3,0,1));
func = _mm256_load_ps(fPtr+1);
acc = _mm256_add_ps(acc, _mm256_mul_ps(perm, func));

perm = _mm256_shuffle_ps(in, in, _MM_SHUFFLE(1,0,3,2));
func = _mm256_load_ps(fPtr+2);
acc = _mm256_add_ps(acc, _mm256_mul_ps(perm, func));

perm = _mm256_shuffle_ps(in, in, _MM_SHUFFLE(0,1,2,3));
func = _mm256_load_ps(fPtr+3);
acc = _mm256_add_ps(acc, _mm256_mul_ps(perm, func));

これは次のように書き直すことができます。

__m256 perm, func;
__m256 in = _mm256_load_ps(inPtr+x);
__m256 acc = _mm256_setzero_ps();
for(int i=0;i<4;++i)
{
    perm = _mm256_shuffle_ps(in, in, _MM_SHUFFLE(3^i,2^i,1^i,0^i));
    func = _mm256_load_ps(fPtr+i);
    acc = _mm256_add_ps(acc, _mm256_mul_ps(perm, func));
}

_mm256_shuffle_psこれは、3 番目のパラメーターとして即時の整数値のみを受け入れるにもかかわらず、gcc 4.9.1 でコンパイルされます。これは、これiがイミディエイトとして受け入れられることを意味し、ループが展開されたことを意味します。

だから私は興味があります:これはコンパイラによって保証されているものですか?それとも、最適化フラグが変更されたとき、またはgccバージョンが変更されたときにコンパイルエラーを引き起こす可能性がありますか? 他のコンパイラ (msvc、icc、clang...) の使用について

4

1 に答える 1

1

組み込みには即値が必要です。コンパイルが機能するのは、ループをアンロールすることによって定数として最適化されたからです。-O0 を指定してコンパイルすると、次のエラーが発生します。

(...)\lib\gcc\x86_64-w64-mingw32\4.9.2\include\avxintrin.h:331: エラー: 最後の引数は 8 ビットの即値でなければなりません

      __mask);
            ^

同様のケースが icc で報告されています。

https://software.intel.com/en-us/forums/intel-c-compiler/topic/287217

于 2016-03-03T12:42:16.977 に答える