这是post的后续版本。免责声明:我已经完成了零配置,甚至没有应用程序,这纯粹是为了让我了解更多关于矢量化的信息。
我的代码如下。我在一台i3 m370机器上用gcc 4.9.4编译。第一个循环如我所期望的那样向量化了。但是第二个循环检查temp的每个元素并不是向量化的AFAICT,而是所有的“andb”指令。我期望它能用类似于_mm_test_all_ones的东西向量化。这个循环怎么也能向量化呢?第二个问题,我真的希望这是一个更大的循环的一部分。如果我取消注解下面的内容,什么都不会得到矢量化。我怎么才能也得到矢量化呢?
#define ARR_LENGTH 4096
#define block_size 4
typedef float afloat __attribute__ ((__aligned__(16)));
char all_equal_2(afloat *a, afloat *b){
unsigned int i, j;
char r = 1;
unsigned int temp[block_size] __attribute__((aligned(16)));
//for (i=0; i<ARR_LENGTH; i+=block_size){
for (j = 0; j < block_size; ++j) {
temp[j] = (*a) == (*b);
a++;
b++;
}
for (j=0; j<block_size; j++){
r &= temp[j];
}
/*if (r == 0){
break;
}
}*/
return r;
}
并由此产生装配的关键部分:
.cfi_startproc
movaps (%rdi), %xmm0
cmpeqps (%rsi), %xmm0
movdqa .LC0(%rip), %xmm1
pand %xmm0, %xmm1
movaps %xmm1, -24(%rsp)
movl -24(%rsp), %eax
andl $1, %eax
andb -20(%rsp), %al
andb -16(%rsp), %al
andb -12(%rsp), %al
ret
.cfi_endproc
更新:这个post与我的第一个问题类似。在那个问题中,向量是一个原始指针,所以可能出现segfault,但在这里这不是问题。因此AFAIK在这里重新排序比较操作是安全的,但在那里不是。结论可能是一样的。
2条答案
按热度按时间6ju8rftf1#
自动矢量化非常喜欢约简操作,所以技巧是将其转化为约简。
编译成一个很好的循环:
rta7y2nd2#
所以你的循环很小,而且是递归的:迭代N的结果被用作迭代N+1的输入。如果你改变你的第二个循环以允许每次迭代2个操作:
您将看到输出已优化
最后一点,代码优化了,启用了外部循环,我看到了一些优化。2你改变编译选项了吗?