Относительные достоинства вычисления с фиксированной запятой и вычисления с плавающей запятой?

9

У меня есть система цифровой обработки сигналов, которая работает на быстром компьютере x86 с использованием чисел с плавающей запятой двойной точности . Мне пришло в голову, что я на самом деле не использую огромный динамический диапазон представления с плавающей запятой - все величины легко помещаются в диапазоне ± 32768.

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

Конечно, ответ зависит от того, сколько бит доступно для вычисления с фиксированной запятой. Сколько бит точности используют типичные системы с фиксированной запятой? Можно ли эффективно выполнять вычисления с фиксированной запятой, скажем, с 64 битами ( 16-битная целая часть, 48-битная дробная часть ) на x86-64?

Я всегда думал, что вычисления с фиксированной точкой используются только в ситуациях, когда мощность процессора ограничена - имеет ли смысл использовать вычисления с фиксированной точкой, когда мощность процессора не имеет значения?

nibot
источник
Вам действительно нужно больше, чем ~ 15 значащих цифр, которые дает вам значение с плавающей точкой двойной точности? Хотя общие обобщения плохие, я бы сказал, что если вы посмотрите на совокупность всех систем DSP с фиксированной точкой, 16-разрядные целые числа, вероятно, будут наиболее распространенным форматом.
Джейсон Р

Ответы:

7

Числовая точность целых чисел будет лучше, чем числовая точность чисел с плавающей запятой, если целочисленное разрешение лучше. Двойные числа имеют 52 дробных бита, поэтому с плавающей точкой двойной точности разрешение хуже, чем у целых чисел, около , что намного больше, чем 32768 ( 2 15 ). Итак, нет, точность чисел не будет лучше, если вы перейдете к целым числам.252215

Вторая проблема - скорость. Ответ: это зависит от оборудования. Если вы запускаете свою программу на цифровом сигнальном процессоре, который имеет несколько ядер с фиксированной точкой, умножающих / накапливающих, то да, в фиксированной точке это будет намного быстрее. С другой стороны, на чипе x86 в фиксированной точке он, вероятно, будет медленнее . Я однажды сделал именно то, о чем вы говорите, и увеличил время выполнения.

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

Если вы хотите ускорить обработку, способ сделать это - перейти от поплавков двойной точности к поплавкам одинарной точности. Это должно привести к значительному увеличению скорости. Это, конечно, уменьшит вашу числовую точность.

Джим Клэй
источник
Я имел в виду то, что говорит этот ответ, когда я написал свой. Этот лучше. Если я не ошибаюсь, я также где-то читал, что на некоторых компьютерах (может быть, 64-разрядных?) Собственный аппаратный тип с плавающей запятой имеет двойной тип, поэтому использование операций с плавающей запятой одинарной точности (четыре байта) может быть на самом деле медленнее. Во всяком случае, это нужно учитывать.
Хелтонбайкер
Поплавки одинарной точности имеют 23-битные мантиссы, двойные имеют 52- битные .
Пол Р
Я предлагаю 16-битное целое + 48-битную дробь в качестве альтернативы с плавающей запятой двойной точности. Я упомянул 32768, чтобы указать, что мои значения легко вписываются в этот диапазон. Учитывая ограничение на эти значения, я думаю, что Q16.48 обеспечит большую числовую точность, чем плавающая точка двойной точности.
нибот
1
@nibot Хорошо. Двойные числа имели бы лучшую точность от -16 до +16, а дробные целые числа имели бы лучшую точность в других местах до -32769 и +32768. Они не могли, конечно, представлять что-либо кроме этого. Они также будут медленнее, чем двойники. Для меня ограниченный диапазон и медленная скорость были бы прерывателями, но YMMV.
Джим Клэй
6

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

Однако огромное количество распространенных современных процессоров (серверных, ПК и даже мобильных) имеют больше и более быстрые FPU (особенно блоки FP одинарной точности), чем целочисленные множители, и большая часть мощности системы не от использования FPU, поэтому использование фиксированного -point будет иметь небольшие преимущества или вообще не иметь преимуществ для типичных вычислений DSP на этих продуктах и, вероятно, может быть недостатком с точки зрения чистой производительности. Используя современные технологии, любое преимущество с фиксированной точкой будет в основном накапливаться в крошечных встроенных продуктах, таких как устройства размером с кнопку.

Однако также учтите следы памяти и кэш-памяти процессора. Умное использование меньших типов данных (short int и float) для полного размещения больших вычислений в кеше данных может свести на нет любые преимущества чистой полосы пропускания FPU.

hotpaw2
источник
2
+1 за упоминание о важности проблем с кешем для производительности. На современных процессорах x86 разработка алгоритма с учетом кеша может сильно повлиять на производительность.
Джейсон Р
5

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

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

Пол Р
источник
Я заинтересован в увеличении числовой точности, а не в ее снижении.
нибот
Как вы видите фиксированную точку, улучшающую числовую точность по сравнению с двойной, которая имеет 52 бит точности и уже огромный динамический диапазон?
Пол Р
Ну, я мог бы использовать формат с фиксированной точкой с более чем 52 битами.
нибот
Поскольку для целочисленной части представления с фиксированной запятой вам, по-видимому, нужно по крайней мере 16 бит, это займет у вас более 64 бит, поэтому вы, вероятно, затем просматриваете формат, для которого ваш ЦП даже не имеет собственных целочисленных инструкций. В этом случае вы можете просто использовать существующую библиотеку с большими целыми числами или аналогичную. Самый важный вопрос, на который нужно ответить: сколько точности вам действительно нужно ?
Пол Р
3

В дополнение к очень хорошим ответам, приведенным здесь, стоит добавить несколько вещей:

  • Существуют ситуации, в которых, даже если у вас есть очень базовые требования к динамическому диапазону обрабатываемых данных, вам все равно потребуется очень хорошая точность для некоторых операций, выполняемых над ним - например, вы захотите применить фильтр БИХ, который требует относительно небольших коэффициентов; и усечение их приведет к нестабильности. Как только ваша система получит обратную связь, есть большая вероятность того, что проблемы с квантованием / усечением укусят вас назад при использовании фиксированной точки - вы должны быть намного осторожнее с такими вещами, как топология фильтра и схемы сокращения / усечения дроби.
  • В отличие от многих архитектур DSP / DSC, x86 не имеет насыщенных целочисленных операций (ну, это есть в SSE, а не в стандартном скалярном коде). Это означает, что в случае переполнения могут произойти плохие вещи - изменение значений знаков и «обтекание». Вы должны быть особенно осторожны с переполнениями и динамическим диапазоном, или тестами разбрызгивания на диапазонах операндовпо всему вашему коду. Это может серьезно повредить производительности. Для сравнения, с плавающей запятой более устойчивы к этим проблемам, потому что большой динамический диапазон дает вам больше «запаса», а переполнение не приведет к катастрофическим сбоям. Большая часть кода обработки аудиосигнала, выполняемого на настольных компьютерах, использует диапазон -1,0 .. 1,0 с одинарной или двойной точностью; так что это дает более сотни дБ запаса мощности. Я написал код обработки аудиосигнала с обоими подходами, и при использовании плавающей запятой, есть только несколько мест, где мне приходится явно обрезать / насыщать сигнал - обычно только в конце цепочки обработки сигналов или в местах, где возникает обратная связь.
pichenettes
источник
1

Некоторые моменты для рассмотрения:

  • Большинство современных процессоров оптимизировали обработку чисел с плавающей запятой в течение многих лет, и даже графические процессоры используются для этого уже очень успешно;
  • Расчеты с фиксированной точкой наносят вред вашим данным и могут вызвать серьезные проблемы, когда арифметические операции не очень хорошо обусловлены (поэтому числа с фиксированной точкой были заменены числами с плавающей точкой);
  • Даже если вы используете подписанные шорты для СОДЕРЖАНИЯ ваших данных (многие регистраторы данных используют 16-битную точность), РАСЧЕТЫ должны быть выполнены с плавающей запятой, а затем преобразованы обратно в целые числа, иначе могут быть такие артефакты, как квантование и псевдонимы.

В качестве последнего слова, я думаю, что наши данные в реальном мире ценны, и слепое сжатие чисел компьютера - скромная черствая работа. Компьютер должен быть установлен, чтобы выполнять тяжелую работу для ваших данных и для вас, и не должен восприниматься как настоящая звезда шоу.

heltonbiker
источник
Я не хотел подразумевать, что я буду использовать 16-битные шорты для хранения моих величин, а скорее что-то вроде 64-битного формата с фиксированной запятой с 16-битной целочисленной частью и 48-битной дробной частью. Мотивация заключается в том, что, если я все равно не буду использовать большинство битов экспоненты в формате с плавающей запятой, улучшится ли моя численная точность, если я вместо этого использую эти биты для предоставления дополнительных значащих цифр?
нибот
215
Еще одна вещь: мне кажется, что StackOverflow (вместо DSP.SE, здесь) будет идеальным местом для получения более глубоких рассуждений о плюсах и минусах одного формата по сравнению с другим.
Хелтонбайкер