GCC自动矢量化在减少循环中失败
gcc auto-vectorization fails in a reduction loop
我试图用自动矢量化标志编译我的代码,但是我在一个非常简单的还原循环中遇到了故障:
double node3::GetSum(void){
double sum=0.;
for(int i=0;i<8;i++) sum+=c_value[i];
return sum;
}
c_value[i]
数组的定义为
class node3{
private:
double c_value[9];
自动矢量化汇编返回: 在Node3.CPP上分析循环:10
node3.cpp:10: note: step unknown.
node3.cpp:10: note: reduction: unsafe fp math optimization: sum_6 = _5 + sum_11;
node3.cpp:10: note: Unknown def-use cycle pattern.
node3.cpp:10: note: Unsupported pattern.
node3.cpp:10: note: not vectorized: unsupported use in stmt.
node3.cpp:10: note: unexpected pattern.
node3.cpp:8: note: vectorized 0 loops in function.
node3.cpp:10: note: Failed to SLP the basic block.
node3.cpp:10: note: not vectorized: failed to find SLP opportunities in basic block.
我真的不明白为什么它不能确定SLP的基本块。而且,我想我不明白什么是" STMT中的不支持的使用":这里的循环简单地总结一个顺序访问数组。
在类的private
中定义了c_value[]
?
预先感谢。
注意:以g++ -c -O3 -ftree-vectorizer-verbose=2 -march=native node3.cpp
的形式编译,并使用更具体的-march=corei7
尝试,但结果相同。GCC版本:4.8.1
我设法在结尾处用以下技巧向量矢量化循环:
double node3::GetSum(void){
double sum=0.,tmp[8];
tmp[0]=c_value[0]; tmp[1]=c_value[1]; tmp[2]=c_value[2]; tmp[3]=c_value[3];
tmp[4]=c_value[4]; tmp[5]=c_value[5]; tmp[6]=c_value[6];tmp[7]=c_value[7];
for(int i=0;i<8;i++) sum+=tmp[i];
return sum;
}
我在哪里创建了虚拟阵列tmp[]
。这个技巧以及另一个汇编标志,即 -funsafe-math-optimizations
(@mysticial:这实际上是我唯一需要的东西,-ffast-math
与其他我显然不需要的其他内容)使自动矢量化成功。
现在,我真的不知道此解决方案是否真的会加快执行力。它确实向量化,但我添加了一个分配操作,因此我不确定是否会更快地运行。我的感觉是,从长远来看(多次调用功能),它确实会加快速度,但我无法证明这一点。无论如何,这是解决矢量化问题的可能解决方案,因此我将其作为答案发布。
矢量化减少的自由与其他(字面上)不安全的优化相结合,这很烦人。在我的示例中,一个错误是通过-mavx和-funsafe -math -math -optimizations浮出水面(与GCC但不是G ),其中永远不要触摸的指针被抓住。自动矢量化并不能始终如一地加快如此短的循环,尤其是因为使用HADD指令的总和表曲线减少了更常见的CPU。
- C/C++:socket() 创建在循环中失败,打开的文件太多
- 谁能弄清楚为什么我的循环会失败?
- 断言失败:列出迭代器不可递增(不在循环中)
- 对于循环执行失败,因为变量我不会递增,为什么?
- GCC自动矢量化在减少循环中失败
- 密码检查程序-匹配密码失败-循环失败
- c++ 中带有容器迭代器的循环类型依赖关系(GCC 失败,而 MSVC 正常)
- 线程未正确结束:它忽略失败的循环条件
- 在循环中第二次调用luaT_pushudata时失败
- 在for循环内部使用setw是失败的
- 用于循环计数器失败的 C++
- 输入验证循环在第一次输入失败后无法正常工作
- std::vector push_back 在并行 for 循环中使用时失败
- 循环迭代后共享指针断言失败
- 对于循环不递增或循环不失败测试
- fgetwc EOF 循环测试失败,但 65535 正常
- 在字符串上循环以查看字符串失败的位置
- 当循环失败时,当读取int和字符串C++时
- 迭代器结束检查在“for”循环内递增后失败
- c++编程,登录尝试,while循环失败