Субнормальные числа, ранее известные как денормальные числа в литературе с плавающей точкой, заполняют погрешность нижнего потока около нуля в арифметике с плавающей точкой. Субнормальные значения являются специальной категорией значений с плавающей точкой, которые слишком близки к 0.0
для представления в виде нормированного значения. Начальное значение и (мантисса) субнормального числа равны нулю. При добавлении и вычитании чисел с плавающей запятой субнормальные числа предотвращают подток.
Использование субнормальных чисел обеспечивает точность сверх нормального представления путем использования ведущих нулей в значении и представлять меньшие значения после того, как представление достигает минимальной степени. Когда значение приближается 0.0
, вы торгуете точностью для расширенной области значений. Субнормальные числа полезны, если ваше приложение требует дополнительной области значений.
Однако в системе реального времени использование субнормальных чисел может значительно увеличить задержку выполнения, что приводит к чрезмерным запасам проекта и переполнениям в реальном времени. Если симуляция или сгенерированный код выполняет вычисления, которые производят или используют субнормальные числа, выполнение этих вычислений может быть до 50 раз медленнее, чем аналогичные вычисления на нормальных числах. Фактическая симуляция или время выполнения кода для вычисления субнормальных чисел зависят от рабочего окружения компьютера. Как правило, для процессоров для настольных ПК время выполнения вычислений субнормальных чисел в пять раз медленнее, чем аналогичные вычисления для нормальных чисел.
Чтобы минимизировать возможность замедления или переполнения выполнения из-за задержки вычисления субнормального числа, выполните одно из следующих действий:
В вашей модели вручную промывайте, чтобы нуль любые входящие или вычисленные субнормальные значения на входах и ключевых операциях, таких как омывания и фильтры. Для получения примера смотрите Flush Subnormal Numbers to Нуля.
Чтобы обнаружить субнормальное значение для одинарной точности, 32-битное число с плавающей запятой:
Нахождение наименьшего нормированного числа в MATLAB® хост. В Командном окне введите:
>> SmallestNormalSingle = realmin('single')
FLT_MIN
, заданный в float.h
, эквивалентно realmin('single')
.Проверьте значения в области значений:
0 < fabsf(x) < SmallestNormalSingle
Чтобы обнаружить субнормальное значение для двойной точности, 64-битное число с плавающей запятой:
Нахождение наименьшего нормированного числа на хосте MATLAB. В Командном окне введите:
>> SmallestNormalDouble = realmin('double')
DBL_MIN
, заданный в float.h
, эквивалентно realmin('double')
.Чтобы обнаружить субнормальное значение, проверьте значения в этой области значений:
0 < fabs(x) < SmallestNormalDouble
Установите параметр Simulation behavior for denormal numbers равным Flush to zero (FTZ)
для эмуляции поведения flush-to-zero для всех денормальных результатов арифметических операций. Для получения дополнительной информации смотрите Поведение симуляции для денормальных чисел.
На вашем процессоре установите режим flush-to-zero или с помощью компилятора задайте опцию отключения субнормальных чисел. Режимы flush-to-zero обрабатывают субнормальное число как 0, когда оно является входом к операции с плавающей точкой. Исключения из подтекста не происходят в режиме flush-to-zero.
Например, в процессорах Intel ® флеш-на-нуле (FTZ) и денормалы-нули (DAZ) флаги в регистре MXCSR управляют вычислениями с плавающей точкой. Для компилятора gcc на Linux, -ffast-math
устанавливает резкое нижнее течение (FTZ), flush-to-zero, в то время как –O3 -ffast-math
возвращается к постепенному нижнему течению с использованием субнормальных чисел.
Для получения дополнительной информации см. IEEE® Стандарт 754, стандарт IEEE для арифметики с плавающей точкой.
Эта модель показывает, как использование субнормальных чисел увеличивает время симуляции ~ в 5 раз.
Откройте ex_subnormal модели. Коэффициент усиления устанавливается на субнормальное значение realmin('double')/2
.
Чтобы запустить симуляцию, в Командном окне введите for k=1:5, tic; sim('ex_subnormal'); toc,end
. Наблюдайте прошедшее время для симуляции с использованием поднормалей, аналогично следующему:
>> for k=1:5, tic; sim('ex_subnormal'); toc,end Elapsed time is 9.909326 seconds. Elapsed time is 9.617966 seconds. Elapsed time is 9.797183 seconds. Elapsed time is 9.702397 seconds. Elapsed time is 9.893946 seconds.
Установите коэффициент усиления равным числу, 2
, что не является субнормальным значением:
>> set_param('ex_subnormal/Gain', 'Gain', '2');
Чтобы запустить симуляцию, в Командном окне введите for k=1:5, tic; sim('ex_subnormal'); toc,end
. Наблюдайте прошедшее время для симуляций, которые не используют субнормальные значения, подобные следующим:
>> for k=1:5, tic; sim('ex_subnormal'); toc,end Elapsed time is 2.045123 seconds. Elapsed time is 1.796598 seconds. Elapsed time is 1.758458 seconds. Elapsed time is 1.721721 seconds. Elapsed time is 1.780569 seconds.
В этом примере показано, как очистить субнормальные числа одной точности до нуля.
Откройте модель ex_flush_to_zero:
Repeating Sequence Stair
генерирует последовательность чисел из двух, повышенных до степени от 0 до двух, повышенных до степени -165. Последовательность приближается к нулю.
ConditionRealScalar
промывает субнормальные значения одинарной точности, которые меньше realmin('single')
в нуль.
Блок MATLAB function log2
генерирует основу 2 Repeating Sequence Stair
выход. В частности, log2
генерирует числа от 0 до -165.
На панели Simulation Step Back > Configure simulation stepping >:
Выберите Enable stepping back.
Выберите Pause simulation when time reaches и введите 121
.
В окне модели запустите симуляцию. Симуляция останавливается на T=121
. Отображаемые значения:
ConditionRealScalar
выход приближается к нулю.
Repeating Sequence Stair output
приближается к нулю.
Переместите симуляцию вперед, чтобы T=127
. ConditionRealScalar
очищает субнормальное значение, выводимое из Repeating Sequence Stair
в нуль.
Продолжите шаг симуляции вперед. ConditionRealScalar
очищает субнормальные значения одинарной точности, выведенные из Repeating Sequence Stair
в нуль. Когда T=150
, выход Repeating Squence Stair
сама по себе равна нулю.