编译器(gcc)能否保证c ++循环

Can c++ loops be guaranteed by the compiler (gcc)?

本文关键字:循环 gcc 编译器      更新时间:2023-10-16

我必须进行以下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只接受即时整数值作为第三个参数。这意味着,i被接受为即时,因此意味着循环已经展开。

所以我很好奇:这是编译器保证的,还是在修改优化标志或 gcc 版本更改时导致编译错误?使用其他编译器(msvc,icc,clang...)怎么样?

内部函数确实需要一个即时值。编译之所以有效,只是因为它通过展开循环优化为常量,并且使用 -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