Gcc 通用条款第6.3.1条不适用于';t仅在不使用模糊数学的情况下自动矢量化

Gcc 通用条款第6.3.1条不适用于';t仅在不使用模糊数学的情况下自动矢量化,gcc,arm,neon,armv7,auto-vectorization,Gcc,Arm,Neon,Armv7,Auto Vectorization,我想理解为什么GCC不自动向量化以下循环,除非我只通过-ffinite数学。根据我的理解和GCC手册,优化需要-funsafe数学优化 如果选定的浮点硬件包括NEON扩展(例如,-mfpu=NEON),请注意,除非还指定了-funsafe数学优化,否则浮点操作不会由GCC的自动矢量化过程生成。这是因为霓虹灯 硬件没有完全实现IEEE 754浮点运算标准(特别是非规范值被视为零),因此使用NEON指令可能会导致精度损失 特别是,该标志使编译器能够采用关联数学,因此它可以首先使用4个部分和进行累加。

我想理解为什么GCC不自动向量化以下循环,除非我只通过-ffinite数学。根据我的理解和GCC手册,优化需要
-funsafe数学优化

如果选定的浮点硬件包括NEON扩展(例如,-mfpu=NEON),请注意,除非还指定了-funsafe数学优化,否则浮点操作不会由GCC的自动矢量化过程生成。这是因为霓虹灯 硬件没有完全实现IEEE 754浮点运算标准(特别是非规范值被视为零),因此使用NEON指令可能会导致精度损失

特别是,该标志使编译器能够采用关联数学,因此它可以首先使用4个部分和进行累加。代码似乎很简单

template<typename SumType = double>
class UipLineResult {
public:
   SumType sqsum;
   SumType dcsum;
   float pkp;
   float pkn;

public:
   UipLineResult() {
      clear();
   }

   void clear() {
      sqsum = 0;
      dcsum = 0;
      pkp = -std::numeric_limits<float>::max();
      pkn = +std::numeric_limits<float>::max();
   }
};
使用
-ffinite math only
这将成为

      intermediate.sqsum += s * s;
1054c:       ef40 6df0       vmla.f32        q11, q8, q8
编译器标志

-funsafe数学优化-仅限ffinite数学-mcpu=cortex-a9-mfpu=neon


我有点惊讶你居然能把那个循环矢量化。GCC不知道如何将条件向量化。在这种情况下,我通常只编写内部函数,而不是浪费时间与编译器的限制抗争。@BitBank使用
vmaxq
vminq
对带有条件的最小-最大值进行矢量化,这里。所以基本上你是在问为什么-funsafe数学优化并不意味着-ffinite数学而已?gcc只需要-ffinite数学来识别
(aVectorization通常是全部或全部。如果你开始拆分向量并重新构建它,你很快就会失去它的好处。在这种情况下,它是可行的,可以通过展开或循环拆分,但这有点专业化。
      intermediate.sqsum += s * s;
107da:       ee47 6aa7       vmla.f32        s13, s15, s15
      intermediate.sqsum += s * s;
1054c:       ef40 6df0       vmla.f32        q11, q8, q8