Плавающая точка против фиксированной точки:какие плюсы/минусы?

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

Вопрос

Тип с плавающей запятой представляет число, сохраняя его значащие цифры и показатель степени отдельно в отдельных двоичных словах, поэтому оно помещается в 16, 32, 64 или 128 бит.

Тип с фиксированной точкой хранит числа с двумя словами, одно представляет целую часть, другое представляет часть после системы счисления, в отрицательных показателях: 2^-1, 2^-2, 2^-3 и т. д.

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

Что касается производительности, какой из них имеет лучшую производительность, или есть случаи, когда один из них быстрее другого?

Все ли в программировании видеоигр используют числа с плавающей запятой, потому что FPU делает это быстрее, или потому что падение производительности незначительно, или они создают свой собственный фиксированный тип?

Почему в C/C++ нет фиксированного типа?

Это было полезно?

Решение

Это определение охватывает очень ограниченное подмножество реализаций фиксированной точки.

Было бы более правильно сказать, что в фиксированной точке хранятся только мантисса, и экспонент является постоянным определенным априорией. Для двоичного пункта нет необходимости падения внутри мантиссы, и, безусловно, не требовалось, чтобы он упал на границу слова. Например, все следующие являются «фиксированной точки»:

  • 64-битная мантисса, масштабированная на 2-32 (Это соответствует определению, указанному в вопросе)
  • 64-битная мантисса, масштабированная на 2-33 (Теперь целочисленные и дробные части не могут быть разделены границей октета)
  • 32-битная мантисса, масштабированная на 24 (сейчас нет дробной части)
  • 32-битная мантисса, масштабированная на 2-40 (сейчас нет целой части)

GPU, как правило, используют фиксированную точку без целой части (обычно 32-битная мантисса, масштабированная на 2-32). Поэтому API, такие как OpenGL и Direct3D, часто используют типы плавающих точек, которые способны удерживать эти значения. Тем не менее, манипулирование целой Mantissa часто более эффективно, поэтому эти API позволяют определять координаты (в текстуре пространство, цветное пространство и т. Д.).

Что касается вашей заявки, что C ++ не имеет фиксированной точки, я не согласен. Все целочисленные типы в C ++ являются типы фиксированных точек. Предполагается, что экспонент часто предполагается, что это нулю, но это не требуется, и у меня есть довольно небольшое количество DSP-точка, реализованного в C ++.

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

На уровне кода арифметика с фиксированной точкой - просто целочисленная арифметика с подразумеваемым знаменателем.

Для многих простых арифметических операций с фиксированной точкой и целочисленными операциями по существу одинаковы. Тем не менее, существуют некоторые операции, которые промежуточные значения должны быть представлены с более высоким количеством битов, а затем закруглены. Например, для умножения двух 16-битных чисел фиксированной точки, результат должен временно храниться в 32-битной перед перенормированием (или насыщенной) обратно в 16-битную фиксированную точку.

Когда программное обеспечение не воспользуется преимуществами векторизации (например, CPU SIMD или GPGPU), целочисленные и арифметика с фиксированной точкой быстрее, чем FPU. При использовании векторизации эффективность векторизации имеет значение намного больше, так что различия на производительности между фиксированной точкой и плавающей точкой является спорным.

Некоторые архитектуры предоставляют аппаратные реализации для определенных математических функций, таких как sin, cos, atan, sqrt, только для типов плавающих точек. Некоторые архитектуры не обеспечивают никаких аппаратных реализации вообще. В обоих случаях специализированные программные библиотеки Math Math могут предоставлять эти функции, используя только целочисленное или арифметику фиксированной точки. Часто такие библиотеки будут обеспечивать множество претензий, например, ответы, которые являются только точны до N-битов точности, что меньше, чем полная точность представления. Ограниченные прецизионные версии могут быть быстрее, чем самая высокая точность.

Фиксированная точка широко используется в DSP и встраиваемых системах, где часто целевой процессор не имеет FPU, а фиксированная точка может быть реализована достаточно эффективно с использованием целочисленного alu.

С точки зрения производительности, это нравится варьироваться в зависимости от целевой архитектуры и применения. Очевидно, что если нет FPU, то фиксированная точка будет значительно быстрее. Когда у вас есть FPU, он будет зависеть от приложения тоже. Например, выполнение таких функций, таких как SQRT () или log (), будет намного быстрее, когда непосредственно поддерживается в инструкции, скорее реализовано алгоритмически.

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

В C ++ определяя класс типа данных фиксированной точки с подходящими перегрузками оператора и связанные с ними математическими функциями, может легко преодолеть этот короткоцентризм. Однако есть хорошие и плохие решения этой проблемы. А. хорошо Пример можно найти здесь: http://www.drdobbs.com/cpp /207000448.. Отказ Ссылка на код в этой статье нарушена, но я отслеживал его до ftp://66.77.27.238/sourcecode/ddj/2008/0804.zip.

Размерность между плавающей точкой и целым математикой зависит от процессора, который вы имеете в виду. На фишках Intel разница не большая в Clockticks. INT Math все еще быстрее, потому что есть несколько целых alu, которые могут работать параллельно. Компиляторы также являются умными для использования специальных инструкций расчета адинт, чтобы оптимизировать добавку / умножение в одну инструкцию. Преобразование считается как операция тоже, поэтому просто выберите свой тип и придерживайтесь его.

В C ++ вы можете создать свой собственный тип для математической точки. Вы просто определяете как структуру с одним int и переопределите соответствующие перегрузки и заставляют их делать то, что они обычно делают плюс сдвиг, чтобы вернуть запятую на правильное положение.

Вы должны быть осторожны при обсуждении «точности» в этом контексте.

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

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

И так далее.

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

Например, вы можете определить ширину экрана/окна просмотра от 0,0 до 1,0, высоту экрана от 0,0 до 1,0.Глубина слова от 0,0 до 1,0.и так далее.Матричная математика и т. д. значительно упрощают реализацию.Проделайте все математические расчеты до момента, когда вам нужно будет вычислить реальные пиксели на реальном размере экрана, скажем, 800x400.Спроецируйте луч из глаза в точку на объекте в мире и вычислите, где он проходит через экран, используя математические вычисления от 0 до 1, затем умножьте x на 800, y умножьте на 400 и поместите этот пиксель.

с плавающей запятой экспонента и мантисса не хранятся отдельно, а мантисса — это глупое число, то, что остается после экспоненты и знака, например, 23 бита, а не 16, 32 или 64 бита.

Математика с плавающей запятой по своей сути использует логику с фиксированной запятой с дополнительной логикой и необходимыми дополнительными шагами.По определению, математика с фиксированной запятой по сравнению с яблоками дешевле, потому что вам не нужно манипулировать данными на пути к alu и не нужно манипулировать данными на выходе (нормализовать).Когда вы добавляете IEEE и весь этот мусор, который добавляет еще больше логики, больше тактов и т.д.(правильно подписанная бесконечность, тихий и сигнальный nan, разные результаты для одной и той же операции, если включен обработчик исключений).Как кто-то отметил в комментарии, в реальной системе, где вы можете выполнять фиксированные и плавающие операции параллельно, вы можете воспользоваться преимуществами некоторых или всех процессоров и таким образом восстановить некоторые тактовые частоты.Как с плавающей, так и с фиксированной тактовой частотой можно увеличить, используя огромные объемы памяти чипа, фиксированная останется дешевле, но с плавающей запятой можно приблизиться к фиксированным частотам с помощью подобных приемов, а также параллельной работы.

Одним из проблем не охватывается, ответы являются энергопотреблением. Хотя он высоко зависит от конкретной архитектуры аппаратного обеспечения, обычно FPU потребляет гораздо больше энергии, чем ALU в процессоре, поэтому, если вы нацеливаете мобильные приложения, в которых важно потребление энергии, это стоит рассмотреть возможность неподвижного точка алгоритма.

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

Плюсы и минусы сводится к скорости и ресурсам. На современных 32-битных и 64-битных платформах на самом деле нет необходимости использовать фиксированную точку. Большинство систем поставляются со встроенным в FPU, которые встроены для оптимизации для операций с фиксированной точкой. Кроме того, большинство современных вторжений ЦП поставляются с такими операциями, как SIMD-набор, который помогает оптимизировать векторные методы на основе вектора и развертывания. Таким образом, фиксированная точка поставляется только с пакой вниз.

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

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