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));
}

这在 gcc 4.9.1 中编译,尽管_mm256_shuffle_ps只接受立即整数值作为第三个参数。这意味着,thati被接受为立即数,因此意味着循环已展开。

所以我很好奇:这是编译器保证的,还是当优化标志被修改或 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 回答