繁体   English   中英

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中不支持的使用”:这里的循环简单地总结了一个顺序访问数组。

c_value[]是否在类的private中定义,是否会导致此类问题?

提前致谢。

注意:编译为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-optimizations组合出现了一个错误(使用gcc而不是g ++),其中一个永远不会被触及的指针会被破坏。 自动向量化并不能始终如一地加速这种短循环,特别是因为在更常见的CPU上使用hadd指令的总和减少结尾很慢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM