我正在尝试将对齐函数的内部循环矢量化,遇到了一个我不理解的问题。当比较输入数组中连续的两个元素时,循环不进行矢量化,但是当被比较的元素偏移2时,它成功地进行矢量化。一个简单的例子:
int *vec_test(int *input) {
int i, n1, n2;
int *out = (int *) malloc(100 * sizeof(int));
// This loop fails to vectorize
for(i=1;i<100;i++) {
n1 = input[i-1];
n2 = input[i];
out[i] = n1 > n2 ? n1 : n2;
}
// This loop successfully vectorizes
for(i=1;i<100;i++) {
n1 = input[i-1];
n2 = input[i+1];
out[i] = n1 > n2 ? n1 : n2;
}
return(out);
}
当我使用clang编译这段代码(clang++-O2-Rpass=loop vectorize-Rpass analysis=loop vectorize-c minimal.cpp)时,第二个循环将矢量化,但第一个循环不会。
minimal.cpp:17:17:备注:循环未矢量化:无法
是
标识为还原在循环外使用
最小。cpp:23:3:备注:矢量化循环(矢量化因子:4,
展开
交织因子:1)[-Rpass=循环矢量化]
唯一的区别是被比较的元素在第一个循环中是连续的,在第二个循环中偏移2。为什么第一个循环无法矢量化?
编辑:用不同宽度类型(int64、int32或int16)替换in t在所有情况下都会产生相同的结果:底部循环矢量化,顶部循环无法这样做。
最佳答案
这个失败看起来像是clang~3.8中的一个bug,已经由3.9.0解决了。
$ clang++ -O2 -Rpass=loop-vectorize -Rpass-analysis=loop-vectorize -c minimal.cpp
minimal.cpp:8:3: remark: the cost-model indicates that interleaving is not beneficial [-Rpass-analysis=loop-vectorize]
for(i=1;i<100;i++) {
^
minimal.cpp:8:3: remark: vectorized loop (vectorization width: 4, interleaved count: 1) [-Rpass=loop-vectorize]
minimal.cpp:15:3: remark: the cost-model indicates that interleaving is not beneficial [-Rpass-analysis=loop-vectorize]
for(i=1;i<100;i++) {
^
minimal.cpp:15:3: remark: vectorized loop (vectorization width: 4, interleaved count: 1) [-Rpass=loop-vectorize]
$ clang++ --version
clang version 3.9.0 (tags/RELEASE_390/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /opt/clang-latest/bin
另见https://godbolt.org/g/Nw0kk1
关于c - 比较顺序数组元素时Clang无法向量化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33489964/