Подтвердить что ты не робот

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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

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

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

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

Ответ 3

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

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

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

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

Ответ 4

Дифференциал между математикой с плавающей запятой и целым числом зависит от процессора, который вы имеете в виду. На чипах Intel разница невелика в clockticks. Int-математика все еще быстрее, потому что существует несколько целых ALU, которые могут работать параллельно. Компиляторы также умеют использовать специальные инструкции расчета адресов для оптимизации добавления/умножения в одной команде. Конверсия также считается операцией, поэтому просто выберите свой тип и придерживайтесь его.

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

Ответ 5

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

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

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

И так далее.

Ответ 6

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

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

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

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

Ответ 7

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

Ответ 8

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

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

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