stringtranslate.com

Субнормальное число

Нерасширенная система с плавающей точкой будет содержать только нормализованные числа (обозначены красным). Разрешение денормализованных чисел (синего цвета) расширяет диапазон системы.

В информатике субнормальные числа — это подмножество денормализованных чисел (иногда называемых денормалами ), которые заполняют зазор вокруг нуля в арифметике с плавающей точкой . Любое ненулевое число с величиной, меньшей наименьшего положительного нормального числа, является субнормальным , в то время как денормал может также относиться к числам за пределами этого диапазона.

Терминология

В некоторых старых документах (особенно в документах стандартов, таких как начальные выпуски IEEE 754 и язык C ) термин «денормальный» используется для обозначения исключительно субнормальных чисел. Такое использование сохраняется в различных документах стандартов, особенно при обсуждении оборудования, которое не способно представлять какие-либо другие денормализованные числа, но в данном обсуждении термин «субнормальный» используется в соответствии с редакцией IEEE 754 2008 года . В неформальных обсуждениях термины субнормальный и денормальный часто используются взаимозаменяемо, отчасти потому, что нет денормализованных двоичных чисел IEEE за пределами субнормального диапазона.

Термин «число» используется довольно свободно, для описания определенной последовательности цифр, а не математической абстракции; см. раздел Плавающая точка для получения подробной информации о том, как действительные числа соотносятся с представлениями с плавающей точкой. «Представление» вместо «числа» может использоваться, когда требуется ясность.

Определение

Математические действительные числа могут быть аппроксимированы несколькими представлениями с плавающей точкой. Одно представление определяется как нормальное , а другие определяются как субнормальное , ненормальное или ненормальное по их отношению к нормальному .

В нормальном значении с плавающей точкой нет ведущих нулей в мантиссе (также обычно называемом мантиссой); вместо этого ведущие нули удаляются путем корректировки показателя степени (например, число 0,0123 будет записано как 1,23 × 10 −2 ). Наоборот, денормализованное значение с плавающей точкой имеет мантису с ведущей цифрой, равной нулю. Из них субнормальные числа представляют значения, которые при нормализации имели бы показатели ниже наименьшего представимого показателя (показатель имеет ограниченный диапазон).

Мантисса (или мантисса) числа с плавающей точкой IEEE — это часть числа с плавающей точкой, которая представляет значимые цифры . Для положительного нормализованного числа его можно представить как m 0 . m 1 m 2 m 3 ... m p −2 m p −1 (где m представляет значимую цифру, а p — точность) с ненулевым m 0 . Обратите внимание, что для двоичной системы счисления ведущая двоичная цифра всегда равна 1. В субнормальном числе, поскольку показатель степени — наименьшее возможное значение, ноль является ведущей значащей цифрой (0. m 1 m 2 m 3 ... m p −2 m p −1 ), что позволяет представлять числа ближе к нулю, чем наименьшее нормальное число. Число с плавающей точкой может быть распознано как субнормальное, если его показатель степени — наименьшее возможное значение.

Заполняя таким образом пробел под переполнением, значимые цифры теряются, но не так резко, как при использовании подхода сброса в ноль при под переполнении (отбрасывая все значимые цифры при достижении под переполнении). Поэтому создание субнормального числа иногда называют постепенным под переполнением, потому что это позволяет вычислению медленно терять точность, когда результат мал.

В IEEE 754-2008 ненормальные числа переименованы в субнормальные числа и поддерживаются как в двоичном, так и в десятичном формате. В двоичных форматах обмена субнормальные числа кодируются смещенной экспонентой 0, но интерпретируются со значением наименьшей допустимой экспоненты, которая на единицу больше (т. е. как если бы она была закодирована как 1). В десятичных форматах обмена они не требуют специального кодирования, поскольку формат напрямую поддерживает ненормализованные числа.

Математически говоря, нормализованные числа с плавающей точкой заданного знака приблизительно логарифмически распределены, и, таким образом, любое конечное число с плавающей точкой не может включать ноль . Субнормальные числа с плавающей точкой представляют собой линейно распределенный набор значений, который охватывает промежуток между отрицательными и положительными нормальными числами с плавающей точкой.

Фон

Субнормальные числа гарантируют, что сложение и вычитание чисел с плавающей точкой никогда не приведет к потере значимости; два соседних числа с плавающей точкой всегда имеют представимую ненулевую разницу. Без постепенной потери значимости вычитание a  −  b может привести к потере значимости и дать ноль, даже если значения не равны. Это, в свою очередь, может привести к ошибкам деления на ноль , которые не могут возникнуть при использовании постепенной потери значимости. [1]

Субнормальные числа были реализованы в Intel 8087 , пока писался стандарт IEEE 754. Они были, безусловно, самой спорной функцией в предложении формата KCS , которое в конечном итоге было принято, [2], но эта реализация продемонстрировала, что субнормальные числа могут поддерживаться в практической реализации. Некоторые реализации блоков с плавающей точкой не поддерживают субнормальные числа напрямую в оборудовании, а скорее привязываются к какой-то программной поддержке. Хотя это может быть прозрачно для пользователя, это может привести к тому, что вычисления, которые производят или потребляют субнормальные числа, будут намного медленнее, чем аналогичные вычисления с обычными числами.

ИИЭЭ

В двоичных форматах с плавающей точкой IEEE субнормальные числа представлены как имеющие поле нулевой экспоненты с ненулевым полем мантиссы. [3]

В двоичных форматах с плавающей точкой IEEE других денормализованных чисел не существует, но они существуют в некоторых других форматах, включая десятичные форматы с плавающей точкой IEEE.

Проблемы с производительностью

Некоторые системы обрабатывают субнормальные значения на аппаратном уровне так же, как и нормальные значения. Другие оставляют обработку субнормальных значений системному программному обеспечению («assist»), обрабатывая только нормальные значения и ноль на аппаратном уровне. Обработка субнормальных значений на программном уровне всегда приводит к значительному снижению производительности. Когда субнормальные значения полностью вычисляются на аппаратном уровне, существуют методы реализации, позволяющие обрабатывать их со скоростью, сопоставимой с обычными числами. [4] Однако скорость вычислений остается значительно сниженной на многих современных процессорах x86; в крайних случаях инструкции , включающие субнормальные операнды, могут занимать до 100 дополнительных тактовых циклов, в результате чего самые быстрые инструкции выполняются в шесть раз медленнее. [5] [6]

Эта разница в скорости может быть риском безопасности. Исследователи показали, что она обеспечивает временной побочный канал , который позволяет вредоносному веб-сайту извлекать содержимое страницы с другого сайта внутри веб-браузера. [7]

Некоторые приложения должны содержать код, чтобы избежать субнормальных чисел, либо для поддержания точности, либо для того, чтобы избежать ухудшения производительности в некоторых процессорах. Например, в приложениях обработки звука субнормальные значения обычно представляют собой сигнал настолько тихий, что он находится вне диапазона человеческого слуха. Из-за этого распространенной мерой для предотвращения субнормальных значений на процессорах, где может возникнуть ухудшение производительности, является обрезание сигнала до нуля, как только он достигает субнормальных уровней, или смешивание с чрезвычайно тихим шумовым сигналом. [8] Другие методы предотвращения субнормальных чисел включают добавление смещения постоянного тока, квантование чисел, добавление сигнала Найквиста и т. д. [9] Начиная с расширения процессора SSE2 , Intel предоставила такую ​​функциональность в аппаратном обеспечении ЦП, которая округляет субнормальные числа до нуля. [10]

Отключение субнормальных чисел с плавающей точкой на уровне кода

Intel SSE

Компиляторы Intel C и Fortran включают флаги DAZ(denormals-are-zero) и FTZ(flush-to-zero) для SSE по умолчанию для уровней оптимизации выше -O0. [11] Эффект заключается DAZв том, что входные аргументы, не соответствующие норме, для операций с плавающей точкой обрабатываются как ноль, а эффект заключается в FTZтом, что возвращается ноль вместо числа с плавающей точкой для операций, которые привели бы к числу с плавающей точкой, не соответствующему норме, даже если входные аргументы сами по себе не являются числами с плавающей точкой. Clang и gcc имеют различные состояния по умолчанию в зависимости от платформы и уровня оптимизации.

Несовместимый с C99 метод включения флагов DAZи FTZна целевых объектах, поддерживающих SSE, приведен ниже, но он не поддерживается широко. Известно, что он работает на Mac OS X по крайней мере с 2006 года. [12]

#include <fenv.h> #pragma STDC FENV_ACCESS ON // Устанавливает DAZ и FTZ, затирая другие настройки CSR. // См. https://opensource.apple.com/source/Libm/Libm-287.1/Source/Intel/, fenv.c и fenv.h. fesetenv ( FE_DFL_DISABLE_SSE_DENORMS_ENV ); // fesetenv(FE_DFL_ENV) // Отключить оба, затирая другие настройки CSR. 

Для других платформ x86-SSE, где библиотека C еще не реализовала этот флаг, может работать следующее: [13]

#include <xmmintrin.h> _mm_setcsr ( _mm_getcsr ( ) | 0x0040 ); // DAZ _mm_setcsr ( _mm_getcsr () | 0x8000 ); // FTZ _mm_setcsr ( _mm_getcsr ( ) | 0x8040 ); // Оба _mm_setcsr ( _mm_getcsr () & ~ 0x8040 ); // Отключить оба             

Макросы _MM_SET_DENORMALS_ZERO_MODEи _MM_SET_FLUSH_ZERO_MODEсоздают более читабельный интерфейс для кода выше. [14]

// Чтобы включить DAZ #include <pmmintrin.h> _MM_SET_DENORMALS_ZERO_MODE ( _MM_DENORMALS_ZERO_ON ); // Чтобы включить FTZ #include <xmmintrin.h> _MM_SET_FLUSH_ZERO_MODE ( _MM_FLUSH_ZERO_ON );  

Большинство компиляторов уже предоставляют предыдущий макрос по умолчанию, в противном случае можно использовать следующий фрагмент кода (определение для FTZ аналогично):

#определить _MM_DENORMALS_ZERO_MASK 0x0040 #определить _MM_DENORMALS_ZERO_ON 0x0040 #определить _MM_DENORMALS_ZERO_OFF 0x0000#define _MM_SET_DENORMALS_ZERO_MODE(режим) _mm_setcsr((_mm_getcsr() & ~_MM_DENORMALS_ZERO_MASK) | (режим)) #define _MM_GET_DENORMALS_ZERO_MODE() (_mm_getcsr() & _MM_DENORMALS_ZERO_MASK)

Поведение денормализации по умолчанию предписано ABI , и поэтому корректно работающее программное обеспечение должно сохранять и восстанавливать режим денормализации перед возвратом к вызывающей стороне или вызовом кода в других библиотеках.

РУКА

AArch32 NEON (SIMD) FPU всегда использует режим сброса в ноль [ требуется ссылка ] , что то же самое, что и FTZ + DAZ. Для скалярного FPU и в AArch64 SIMD поведение сброса в ноль является необязательным и контролируется битом FZрегистра управления – FPSCR в Arm32 и FPCR в AArch64. [15]

Один из способов сделать это:

#if defined(__arm64__) || defined(__aarch64__) uint64_t fpcr ; asm ( "mrs %0, fpcr" : "=r" ( fpcr )); //Загрузить регистр FPCR asm ( "msr fpcr, %0" :: "r" ( fpcr | ( 1 << 24 ) )); //Установить 24-й бит (FTZ) в 1 #endif                    

Некоторые процессоры ARM имеют аппаратную обработку субнормальных значений.

Смотрите также

Примечания

Ссылки

  1. ^ Уильям Кахан. "IEEE 754R meeting protocol, 2002". Архивировано из оригинала 15 октября 2016 года . Получено 29 декабря 2013 года .
  2. ^ «Интервью со старым человеком с плавающей точкой». Калифорнийский университет в Беркли.
  3. ^ "Денормализованные числа". Caldera International . Получено 11 октября 2023 г.(Обратите внимание, что в документации XenuOS используется denormal , тогда как в IEEE 754 используется subnormal .)
  4. ^ Шварц, Э. М.; Шмуклер, М.; Сон Дао Тронг (июль 2005 г.). «Реализации FPU с денормализованными числами» (PDF) . IEEE Transactions on Computers . 54 (7): 825–836. doi :10.1109/TC.2005.118. S2CID  26470540.
  5. ^ Дули, Айзек; Кейл, Лакшмикант (12 сентября 2006 г.). «Количественная оценка помех, вызванных субнормальными значениями с плавающей точкой» (PDF) . Получено 30 ноября 2010 г.
  6. ^ Фог, Агнер. "Таблицы инструкций: списки задержек инструкций, пропускной способности и микроопераций для процессоров Intel, AMD и VIA" (PDF) . Получено 25 января 2011 г.
  7. ^ Andrysco, Marc; Kohlbrenner, David; Mowery, Keaton; Jhala, Ranjit; Lerner, Sorin; Shacham, Hovav. «О субнормальной плавающей точке и аномальном времени» (PDF) . Получено 5 октября 2015 г.
  8. ^ Серрис, Джон (16 апреля 2002 г.). «Денормализация Pentium 4: скачки загрузки ЦП в аудиоприложениях». Архивировано из оригинала 25 февраля 2012 г. Получено 29 апреля 2015 г.
  9. ^ де Сорас, Лоран (19 апреля 2005 г.). «Ненормальные числа в приложениях обработки сигналов с плавающей точкой» (PDF) .
  10. Кейси, Шон (16 октября 2008 г.). "x87 и SSE Floating Point Assists in IA-32: Flush-To-Zero (FTZ) and Denormals-Are-Zero (DAZ)" . Получено 3 сентября 2010 г. .
  11. ^ "Библиотека Intel® MPI – Документация". Intel.
  12. ^ "Re: Проблема производительности Macbook pro". Apple Inc. Архивировано из оригинала 26 августа 2016 г.
  13. ^ "Re: Изменение состояния с плавающей точкой (было: производительность double против float)". Apple Inc. Архивировано из оригинала 15 января 2014 года . Получено 24 января 2013 года .
  14. ^ «Руководство пользователя компилятора C++ для систем Linux*». Intel.
  15. ^ "Регистры Aarch64". Арм.

Дальнейшее чтение