Сбрасывать в ноль, когда вычисление приводит к денормальному числу в Linux

Вычисление в моем коде на C приводит к постепенному потере значимости, и когда это происходит, программа завершается с SIGFPE. Как я могу сбросить результат до нуля, когда в результате вычислений возникает постепенное недополнение (Denormal), а не прерывать выполнение? (Я работаю на Linux-машине с RedHat). Спасибо.


person Laplace    schedule 31.07.2013    source источник
comment
Вы сделали что-нибудь особенное, чтобы ваша программа завершилась при потере памяти? Я думал, что в настоящее время недополнение в основном обрабатывается микрокодом, который, хотя и медленнее, чем аппаратная реализация для нормализованных результатов, будет полностью прозрачным для программных слоев.   -  person Pascal Cuoq    schedule 01.08.2013
comment
Есть ли какой-либо флаг, который я могу добавить при компиляции в gcc, чтобы включить FTZ, когда происходит постепенный недолив?   -  person Laplace    schedule 01.08.2013
comment
Вероятно, это не флаг gcc, но код, который вы можете выполнить, безусловно. Однако человек, который сможет ответить на ваш вопрос, может быть заинтересован в том, чтобы узнать, как вы заставили свою программу получать SIGFPE при потере памяти, поскольку это не поведение по умолчанию. Это может быть даже полезная информация, чтобы помочь этому человеку помочь вам.   -  person Pascal Cuoq    schedule 01.08.2013
comment
Вряд ли для вашей программы будет что-то волшебное о денормализованных числах. Если они появляются, у вас также должны быть очень маленькие, но нормализованные числа. Почему они действительны, а денормализованные должны быть равны нулю?   -  person Patricia Shanahan    schedule 01.08.2013
comment
Откуда вы знаете, что происходит постепенный недостаточный поток, и что заставляет вас думать, что это является причиной SIGFPE? Ваш отладчик gdb и, когда программа получает SIGFPE, работают ли команды info float и print $mxcsr? Каков их выход? Что получится, если вы выполните их в начале программы? (Используйте break main, затем run, затем info float и print $mxcsr?) Когда возникает SIGFPE, можете ли вы выполнить x/i $pc, чтобы увидеть неисправную инструкцию, и можете ли вы распечатать содержимое операндов инструкции?   -  person Eric Postpischil    schedule 01.08.2013


Ответы (1)


Вы не указали архитектуру — я предполагаю, что это относительно недавний x86[-64], и в этом случае вы можете манипулировать управляющим регистром SSE, используя _mm_getcsr, _mm_setcsr, указанные в <xmmintrin.h> (или <immintrin.h>) заголовок.

Бит «flush-to-zero» установлен в 0x8000, а «denormals-are-zero» (для inputs/src) установлен в 0x0040.

_mm_setcsr(_mm_getcsr() | 0x8040); или с <pmmintrin.h> (SSE3):

_mm_setcsr(_mm_getcsr() | (_MM_FLUSH_ZERO_ON | _MM_DENORMALS_ZERO_ON));

Это может облегчить определение источника потери значимости, но это не следует рассматривать как решение, поскольку среда FP больше не соответствует стандарту IEEE-754.

person Brett Hale    schedule 01.08.2013