В каждом месте, где я смотрел, написано, что double
оно превосходит float
почти во всех отношениях. float
был сделан устаревшим double
в Java, так почему он все еще используется?
Я много программирую на Libgdx, и они вынуждают вас использовать float
(deltaTime и т. Д.), Но мне кажется, что с ними double
проще работать с точки зрения хранения и памяти.
Я также читаю Когда вы используете float и когда вы используете double , но если float
это действительно хорошо только для чисел с большим количеством цифр после десятичной точки, то почему мы не можем просто использовать один из многих вариантов double
?
Есть ли какая-то причина, по которой люди настаивают на использовании поплавков, хотя у них больше нет преимуществ? Не слишком ли много работы, чтобы все это изменить?
byte
иshort
иint
когда естьlong
?Ответы:
LibGDX - это фреймворк, в основном используемый для разработки игр.
При разработке игр вам, как правило, приходится выполнять множество вычислений в реальном времени, и любая производительность, которую вы можете получить, имеет значение. Вот почему разработчики игр обычно используют float, когда точность float достаточно хороша.
Размер регистров FPU в CPU - не единственное, что вам нужно учитывать в этом случае. Фактически, большая часть значительного сокращения чисел в разработке игр выполняется графическим процессором, а графические процессоры обычно оптимизированы для операций с плавающей запятой, а не для удвоения .
И тогда есть также:
которые являются всеми ценными ресурсами, которые вы получаете вдвое больше, когда используете 32-битный float вместо 64-битного double.
источник
Float использует вдвое больше памяти, чем удваивается.
Они могут иметь меньшую точность, чем двойные, но многие приложения не требуют точности. Они имеют больший диапазон, чем любой аналогичный формат с фиксированной точкой. Таким образом, они занимают нишу, которая нуждается в широком диапазоне чисел, но не требует высокой точности и где важно использование памяти. Например, в прошлом я использовал их для больших нейронных сетей.
Выходя за пределы Java, они также широко используются в трехмерной графике, поскольку многие графические процессоры используют их в качестве основного формата - за исключением очень дорогих устройств NVIDIA Tesla / AMD FirePro, с плавающей запятой двойной точности очень медленно на графических процессорах.
источник
Обратная совместимость
Это причина номер один для сохранения поведения на уже существующем языке / библиотека / ISA / и т. Д.
Подумайте, что случится, если они заберут поплавки из Java. Libgdx (и тысячи других библиотек и программ) не будут работать. Потребуется много усилий, чтобы обновить все, возможно, годы для многих проектов (просто посмотрите на переход с обратной совместимости с Python 2 на Python 3). И не все будет обновлено, некоторые вещи будут сломаны навсегда, потому что сопровождающие отказались от них, возможно, раньше, чем они бы сделали, потому что потребовалось бы больше усилий, чем они хотят обновить, или потому что больше не возможно выполнить то, что предполагалось их программным обеспечением сделать.
Представление
64-битные двойные операции занимают вдвое больше памяти и почти всегда медленнее обрабатываются, чем 32-битные операции с плавающей запятой (за очень редким исключением предполагается, что возможности 32-разрядных операций с плавающей запятой будут использоваться так редко или не используются вообще, что не было предпринято никаких усилий для их оптимизации). Если вы не разрабатываете специализированное оборудование, вы не испытаете этого в ближайшем будущем.)
Libgdx - это библиотека игр. Игры имеют тенденцию быть более чувствительными к производительности, чем большинство программного обеспечения. И игровые видеокарты (то есть AMD Radeon и NVIDIA Geforce, а не FirePro или Quadro), как правило, имеют очень слабую 64-битную производительность с плавающей запятой. Благодаря Anandtech, вот как производительность с двойной точностью сравнивается с производительностью с одинарной точностью на некоторых топовых игровых картах AMD и NVIDIA (по состоянию на начало 2016 года)
Обратите внимание, что серии R9 Fury и GTX 900 являются более новыми, чем серии R9 200 и GTX 700, поэтому относительная производительность для 64-разрядных чисел с плавающей запятой уменьшается. Вернитесь достаточно далеко, и вы найдете GTX 580, который имел соотношение 1/8, как серия R9 200.
1/32 производительности - это довольно большое наказание, если у вас жесткие временные ограничения и вы мало выигрываете, используя больший дубль.
источник
Атомные операции
В дополнение к тому, что уже сказали другие, специфический для Java недостаток
double
(иlong
) состоит в том, что присвоение 64-битным примитивным типам не гарантируется как атомарное . Из спецификации языка Java, Java SE 8 Edition , стр. 660 (выделение добавлено):Тьфу.
Чтобы избежать этого, вы должны объявить 64-битную переменную с
volatile
ключевым словом или использовать другую форму синхронизации вокруг назначений.источник
Кажется, что в других ответах пропущен один важный момент: архитектуры SIMD могут обрабатывать меньше / больше данных в зависимости от того, работают ли они
double
илиfloat
структурируются (например, восемь значений с плавающей запятой за раз или четыре двойных значения за раз).Резюме соображений производительности
float
может быть быстрее на определенных процессорах (например, на определенных мобильных устройствах).float
использует меньше памяти, поэтому в больших наборах данных это может существенно уменьшить общую требуемую память (жесткий диск / RAM) и потребляемую пропускную способность.float
может заставить процессор потреблять меньше энергии (я не могу найти ссылку, но, если это невозможно, по крайней мере, кажется правдоподобным) для вычислений с одинарной точностью по сравнению с вычислениями с двойной точностью.float
потребляет меньше пропускной способности, а в некоторых приложениях это имеет значение.float
использует до половины кэш-памяти по сравнению с двойной.Резюме соображений точности
float
достаточноdouble
в любом случае имеет гораздо больше точностиВопросы совместимости
double
(это потому, что производители графических процессоров пытаются увеличить количество графических ядер, и таким образом, они пытаются сохранить как можно больше схем в каждом ядре, поэтому оптимизацияfloat
позволяет создавать графические процессоры с большим количеством ядер внутри)double
в качестве внутреннего формата (для операций 3D-рендеринга)Общие советы
double
переменных в стеке дает дополнительную точность бесплатно (дополнительную точность без потери производительности).float
, но могут быть ограниченные значения, если вы используетеdouble
)float
или толькоdouble
очень помогает компилятору SIMD-инструкции.Смотрите комментарии ниже от PeterCordes для получения дополнительной информации.
источник
double
Временные программы доступны только на x86 с x87 FPU, но не с SSE2. Автоматическая векторизация цикла сdouble
временными значениями означает распаковкуfloat
вdouble
, что требует дополнительной инструкции, и вы обрабатываете вдвое меньше элементов на вектор. Без автоматической векторизации преобразование может обычно происходить на лету во время загрузки или хранения, но это означает дополнительные инструкции, когда вы смешиваете числа с плавающей запятой и удваивает в выражениях.Помимо других причин, которые были упомянуты:
Если у вас есть данные измерений, будь то давления, потоки, токи, напряжения или что-то еще, это часто делается с помощью оборудования, имеющего АЦП.
АЦП обычно имеет 10 или 12 бит, 14 или 16 бит реже. Но давайте остановимся на 16-битной единице - при измерении по полной шкале точность составляет 1/65535. Это означает, что переход от 65534/65535 к 65535/65535 - именно этот шаг - 1/65535. Это примерно 1.5E-05. Точность поплавка составляет около 1E-07, так что намного лучше. Это означает, что вы ничего не потеряете, используя
float
для хранения этих данных.Если вы выполняете чрезмерные вычисления с плавающими значениями, вы выполняете немного хуже, чем с
doubles
точки зрения точности, но часто вам не нужна эта точность, поскольку вам часто все равно, измеряете ли вы напряжение 2 В или 2,00002 В. Аналогично Если вы преобразуете это напряжение в давление, вам все равно, если у вас 3 бара или 3,00003 бара.источник