【发布时间】:2016-03-03 08:54:00
【问题描述】:
我必须进行以下 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吗?会发生什么? -
另外,您如何得出只支持立即数的结论? GCC implementation 似乎采用了
const int,而the Intel spec 似乎表示相同。 -
const int签名没有说明任何内容,因为语言中没有任何内容指定参数是否为立即数。此外,英特尔内部文档中的任何imm参数都意味着立即数。这在 MSDN 文档中更清楚。最后,在 gcc 中使用非立即数会触发错误:“最后一个参数必须是 8 位立即数”
标签: c++ loop-unrolling