Нулевые денормальные значения - это надежно?

Для обработки сигналов это было проблемой, как всегда, я все еще принимаю меры предосторожности, добавляя небольшую константу всякий раз, когда может произойти денормация, например:

float coef = 0.9f;
for (int i=0; i<cnt; i++) dst[i] = state = state * 0.9f + 1E-15f;

Очевидно, что это вряд ли идеально, но в прошлом у меня было множество проблем, из-за которых, даже если я пытался установить FTZ, на некоторых компьютерах это явно не работало. В настоящее время я использую Intel IPP так:

ippSetDenormAreZeros(b);
const int success = ippSetFlushToZero(b, NULL) == ippStsNoErr;

Так насколько это надежно? Есть ли способ лучше? Надежный способ? К сожалению, мне нужна поддержка, как и все древние процессоры, скажем, Core2duo, Windows и OSX. Однако я обычно использую SSE2 и новее и CLANG с -mfpmath = sse и -ffast-math.


person Vojtěch Melda Meluzín    schedule 19.10.2018    source источник


Ответы (1)


Вы говорите «обычно», но математика x87 не имеет эквивалента битов FTZ / DAZ в MXCSR. Они есть только в математике SSE / AVX. Поэтому, если вы когда-либо компилируете устаревший 32-разрядный код с использованием математики x87, вы все равно можете получить замедление из-за субнормальных явлений, потому что оборудование не имеет средств для отключения для них постепенного истощения. (И x87 также медленный на NaN / Inf, где SSE - нет.)

В общем, связывание с -ffast-math приведет к тому, что ваш компилятор будет связан с кодом запуска CRT, который устанавливает эти биты MXCSR, но в функциях общей библиотеки вы не можете предполагать, что они будут установлены, если вы не установите их самостоятельно. (И помните, что они для каждого потока. Я не уверен, наследуются ли новые потоки от родительского или начинаются с настройками по умолчанию).


Что касается изменения на лету и переупорядочения вызовов функций во время компиляции с независимой математикой FP, компилятор может предположить, что ничего не меняет режим округления FP на лету, если вы не используете #pragma STDC FENV_ACCESS ON в C.

Но это существует только в C, а не в C ++, согласно Имеет ли FENV_ACCESS pragma существует в C ++ 11 и выше?

И на практике компиляторы могут быть не идеальны в этом. Я действительно не знаю. Надеюсь, у кого-то еще есть более конкретный ответ по этому поводу.


Но да, с установленными FTZ и DAZ никакое существующее оборудование x86 никогда не будет иметь каких-либо замедлений с помощью FP при выполнении математических инструкций SSE / AVX.

person Peter Cordes    schedule 22.10.2018