Каковы области применения / преимущества 80-разрядного типа данных повышенной точности?

StackOverflow https://stackoverflow.com/questions/612507

  •  03-07-2019
  •  | 
  •  

Вопрос

Да, я хотел сказать 80-битный.Это не опечатка...

Мой опыт работы с переменными с плавающей запятой всегда включал 4-байтовые кратные, такие как одиночные (32 бита), двойные (64 бита) и длинные двойные (которые, как я видел, обозначаются либо как 96-битные, либо как 128-битные).Вот почему я был немного сбит с толку, когда наткнулся на 80-битный тип данных повышенной точности пока я работал над некоторым кодом для чтения и записи Файлы формата AIFF (Audio Interchange File Format):для хранения частоты дискретизации звуковой дорожки была выбрана расширенная переменная точности.

Когда я бегло просмотрел Википедию, я нашел ссылку выше вместе с кратким упоминанием о 80-битных форматах в Стандарт IEEE 754-1985 краткое содержание (но не в Стандарт IEEE 754-2008 краткое содержание).Похоже, что на определенных архитектурах "extended" и "long double" являются синонимами.

Единственное, с чем я не сталкивался, - это конкретные приложения, которые используют типы данных повышенной точности (за исключением, конечно, частоты дискретизации файлов AIFF).Это заставило меня задуматься:

  • Кто-нибудь сталкивался с ситуацией, когда повышенная точность была необходима / выгодна для какого-либо программного приложения?
  • Каковы преимущества 80-битного числа с плавающей запятой, кроме очевидного "это немного больше точности, чем double, но меньше байтов, чем большинство реализаций long double"?
  • Идет ли на убыль его применимость?
Это было полезно?

Решение

Процессорные процессоры Intel используют 80-разрядный формат для получения большей точности промежуточных результатов.

То есть у вас могут быть 32-разрядные или 64-разрядные переменные, но когда они загружаются в регистры FPU, они преобразуются в 80-разрядные;затем FPU (по умолчанию) выполняет все вычисления в 80, но;после вычисления результат сохраняется обратно в 32-разрядные или 64-разрядные переменные.

BTW - Несколько прискорбным следствием этого является то, что сборки debug и release могут давать несколько разные результаты:в сборке выпуска оптимизатор может сохранить промежуточную переменную в 80-разрядном регистре FPU, в то время как в сборке отладки она будет сохранена в 64-разрядной переменной, что приведет к потере точности.Вы можете избежать этого, используя 80-разрядные переменные, или использовать переключатель FPU (или опцию компилятора) для выполнения всех вычислений в 64-разрядном формате.

Другие советы

Для меня использование 80 бит имеет ВАЖНОЕ ЗНАЧЕНИЕ.Таким образом, я получаю собственные значения высокого порядка (30 000) и собственные векторы симметричных матриц с еще четырьмя цифрами при использовании библиотеки GOTO для векторных внутренних произведений, а именно 13 вместо 9 значащих цифр для типа матриц, которые я использую в релятивистских атомных вычислениях, что необходимо, чтобы избежать попадания в море состояний с отрицательной энергией.Мой другой вариант - использование арифметики с четырехкратной точностью, которая увеличивает время процессора в 60-70 раз, а также увеличивает требования к оперативной памяти.Любое вычисление, основанное на внутренних произведениях больших векторов, принесет пользу.Конечно, чтобы сохранить частичные результаты внутреннего продукта в регистрах, необходимо использовать язык ассемблера, как в библиотеках GOTO.Вот так я полюбил свои старые процессоры Opteron 850, которые я буду использовать до тех пор, пока они будут использоваться для этой части моих вычислений.

Причина, по которой 80 бит - это быстро, в то время как большая точность - намного медленнее, заключается в том, что стандартное аппаратное обеспечение процессора с плавающей запятой имеет 80-битные регистры.Следовательно, если вам нужны дополнительные 16 бит (11 дополнительных битов мантиссы, четыре дополнительных бита экспоненты и один дополнительный бит, фактически неиспользуемый), то расширение с 64 до 80 бит на самом деле не будет стоить вам больших затрат, тогда как расширение за пределы 80 бит чрезвычайно дорого с точки зрения времени выполнения.Таким образом, вы могли бы также использовать 80-битную точность, если хотите.Это не бесплатно в использовании, но стоит довольно дешево.

Википедия объясняет что 80-битный формат может представлять целое 64-битное целое число без потери информации.Таким образом, единица измерения с плавающей запятой центрального процессора может быть использована для реализации умножения и деления целых чисел.

Другое преимущество, еще не упомянутое для 80-разрядных типов, заключается в том, что на 16-разрядных или 32-разрядных процессорах, которые не имеют единиц измерения с плавающей запятой, но имеют инструкцию "умножения", которая выдает результат, вдвое превышающий длину операндов (16x16-> 32 или 32x32-> 64), арифметика в 64-разрядной мантиссе, разделенной на четыре или два 16-разрядных или 32-разрядных регистра, будет быстрее, чем арифметика в 53-разрядной мантиссе, которая охватывает такое же количество регистров, но должна разделять 12 разрядов регистра со знаком и показателем степени.Для приложений, которым не нужно ничего более точного, чем float, вычисления с 48-разрядным типом "extended float" также могут быть быстрее, чем вычисления с 32-разрядным float.

Хотя некоторые люди могут сетовать на двойное округление типов с повышенной точностью, на самом деле это проблема только в специализированных приложениях, требующих кросс-платформенной воспроизводимости с точностью до бита.Из точность с точки зрения, разница между ошибкой округления 64/128 против 65/128 или 1024 / 2048ulp против 1025/2048 не является проблемой;на языках с типы переменных повышенной точности и согласованная семантика расширенной точности, использование расширенных типов на многих платформах без аппаратных средств с плавающей запятой (напримервстроенные системы) обеспечат как более высокую точность, так и лучшую скорость, чем типы с плавающей запятой одинарной или двойной точности.

Я использовал 80-битную версию для некоторых чисто математических исследований.Мне пришлось суммировать слагаемые в бесконечном ряду, который становился довольно большим, за пределами диапазона удвоений.Сходимость и точность не были проблемой, просто способность обрабатывать большие показатели, такие как 1E1000.Возможно, какая-нибудь умная алгебра могла бы упростить ситуацию, но было намного быстрее и проще просто закодировать алгоритм с повышенной точностью, чем тратить время на размышления об этом.

У меня есть друг, который работает в этой сфере.Он работает над библиотекой для обработки чисел с плавающей запятой размером в гигабайт.Конечно, это что-то связанное с научными вычислениями (расчеты с плазмой), и, вероятно, только этот вид вычислений работает с такими большими числами...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top