如何用 AVX2 向量化 a[i] = a[i-1] +c
Posted
技术标签:
【中文标题】如何用 AVX2 向量化 a[i] = a[i-1] +c【英文标题】:how to vectorize a[i] = a[i-1] +c with AVX2 【发布时间】:2017-04-05 07:32:18 【问题描述】:我想通过 AVX2 指令矢量化 a[i] = a[i-1] +c
。由于依赖关系,它似乎无法矢量化。我已经矢量化了,想在这里分享答案,看看这个问题有没有更好的答案或者我的解决方案很好。
【问题讨论】:
请注意,llvm/clang 自动向量化此标量代码,您可能希望将您的解决方案与此进行比较(并可能为其他编译器提交错误报告,要求他们实现此类优化)。此外,写a[i]=b;b+=c;
是由 gcc 向量化的(尽管可能不是最佳的)。
谢谢,我会检查的。 Clang -O3 时间:0.000037 s
GCC -O3 时间:0.000107 s
我的解决方案时间是0.000045 s
所以LLVM
比我的解决方案快
@MarcGlisse,我无法提交错误报告! User account creation filtered due to spam.
当前创建用户帐户的方法是发送电子邮件至监督者@gcc.gnu.org(他们手动完成)。
【参考方案1】:
我已经实现了以下函数来对其进行矢量化,看起来还可以!加速比gcc -O3
提高了 2.5 倍
这是解决方案:
// vectorized
inline void vec(int a[LEN], int b, int c)
// b=1 and c=2 in this case
int i = 0;
a[i++] = b;//0 --> a[0] = 1
//step 1:
//solving dependencies vectorization factor is 8
a[i++] = a[0] + 1*c; //1 --> a[1] = 1 + 2 = 3
a[i++] = a[0] + 2*c; //2 --> a[2] = 1 + 4 = 5
a[i++] = a[0] + 3*c; //3 --> a[3] = 1 + 6 = 7
a[i++] = a[0] + 4*c; //4 --> a[4] = 1 + 8 = 9
a[i++] = a[0] + 5*c; //5 --> a[5] = 1 + 10 = 11
a[i++] = a[0] + 6*c; //6 --> a[6] = 1 + 12 = 13
a[i++] = a[0] + 7*c; //7 --> a[7] = 1 + 14 = 15
// vectorization factor reached
// 8 *c will work for all
//loading the results to an vector
__m256i dep1, dep2; // dep = 1, 3, 5, 7, 9, 11, 13, 15
__m256i coeff = _mm256_set1_epi32(8*c); //coeff = 16, 16, 16, 16, 16, 16, 16, 16
for(; i<LEN-1; i+=16)
dep1 = _mm256_load_si256((__m256i *) &a[i-8]);
dep1 = _mm256_add_epi32(dep1, coeff);
_mm256_store_si256((__m256i *) &a[i], dep1);
dep2 = _mm256_load_si256((__m256i *) &a[i]);
dep2 = _mm256_add_epi32(dep2, coeff);
_mm256_store_si256((__m256i *) &a[i+8], dep2);
【讨论】:
以上是关于如何用 AVX2 向量化 a[i] = a[i-1] +c的主要内容,如果未能解决你的问题,请参考以下文章
A[i]+=A[i+1] 是循环中的一种数据依赖性吗?可以矢量化吗?