GCC 6.3.1 не выполняет авто-векторизацию без -ffinite-math-only

Я хотел бы понять, почему GCC не выполняет авто-векторизацию следующего цикла, если я не передаю -ffinite-math-only. Что касается моего понимания и руководства GCC, оптимизация требует -funsafe-math-optimizations

Если выбранное аппаратное обеспечение с плавающей запятой включает в себя расширение NEON (например, -mfpu=neon), обратите внимание, что операции с плавающей запятой не генерируются проходом автоматической векторизации GCC, если также не указан параметр -funsafe-math-optimizations. Это связано с тем, что аппаратное обеспечение NEON не полностью реализует стандарт 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();
   }
};

Цикл, который не векторизован

static void addSamplesLine(const float* ss, UipLineResult<>* line) {
   UipLineResult<float> intermediate;
   for(int idx = 0; idx < 120; idx++) {
      float s = ss[idx];
      intermediate.sqsum += s * s;
      intermediate.dcsum += s;
      intermediate.pkp = intermediate.pkp < s ? s : intermediate.pkp;
      intermediate.pkn = intermediate.pkn > s ? s : intermediate.pkn;
   }
   line->addIntermediate(&intermediate);
}

Например, квадрат сложения выглядит как

      intermediate.sqsum += s * s;
107da:       ee47 6aa7       vmla.f32        s13, s15, s15

С -ffinite-math-only это становится

      intermediate.sqsum += s * s;
1054c:       ef40 6df0       vmla.f32        q11, q8, q8

Флаги компилятора

-funsafe-math-optimizations -ffinite-math-only -mcpu=cortex-a9 -mfpu= неон

0 ответов

Другие вопросы по тегам