Денормали флеш-ноль - это надежно? - PullRequest
0 голосов
/ 19 октября 2018

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

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.

1 Ответ

0 голосов
/ 22 октября 2018

Вы говорите «в общем», но математика 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 в C ++ 11 и выше?

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


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

...