В настоящее время я пишу небольшой кроссплатформенный движок 2D-игр на базе OpenGL для нашей студии. Когда я исследовал, какой класс 2D Vector использовать, я наткнулся на три разные парадигмы дизайна:
Float & Call-by-value, как в этой статье о Гамасутре . Кажется быстрым, но предлагает мало точности (см. Также эту тему ). Pro: быстрый, портативный и совместимый с большинством библиотек.
Double & Call-по ссылке. Если я правильно понял приведенную выше статью, я мог бы также использовать 2 переменные двойной точности вместо 4 чисел с плавающей точкой. Согласно приведенному выше потоку double все еще медленнее, чем float.
Шаблоны для удвоения и поплавка: в широко популярной книге « Архитектура игрового движка » используются шаблоны, позволяющие использовать поплавки и удвоения при необходимости. Очевидным недостатком является раздувание кода. Кроме того, я сомневаюсь, что код может быть оптимизирован без написания двух классов.
Я был бы признателен, чтобы узнать, какие решения вы используете в своих собственных движках и насколько точны, например, популярные игровые движки, чтобы я мог решить, какое решение я буду внедрять в нашем движке. В данный момент я думаю о том, чтобы просто использовать точность с плавающей точкой и жить с ней.
источник
Ответы:
Я всегда использую float, если у меня нет причины использовать double, так же, как я использую int, если у меня нет причины использовать int64_t.
Поплавки без проблем делают точную целочисленную арифметику до 2 24 , чего большинство людей (в основном иррационально) боятся. Двойные числа не решают проблему того, что обычные значения точно не представлены - независимо от того, получаете ли вы 0,10000001 или 0,10000000000000001, вы все равно должны убедиться, что ваш код считает его «равным» 0,09999999.
Удваивание происходит медленнее на каждой платформе, вам нужно заботиться о написании игр, занимать вдвое большую пропускную способность памяти и иметь меньше специализированных инструкций процессора.
Плавающие с одинарной точностью остаются стандартом для аппаратных графических интерфейсов, как на стороне C / C ++, так и внутри шейдеров.
Возможно, в какой-то момент вам понадобится двойной вектор, но его следует использовать при необходимости, а не по умолчанию.
Что касается шаблонов - вы правы, для максимальной производительности вы все равно захотите специализировать шаблоны вручную. Кроме того, я выполнил несколько тестов для некоторого шаблонного кода в течение выходных (делая 4-элементные IntRect и FloatRect) и обнаружил, что шаблонная версия потребовала примерно в 20 раз больше времени, чем просто повторение кода, что составило около 15 строк , Повторение - отстой, но ожидание компиляции - отстой, а мне не нужно StringRect или FooRect.
источник
Игровая среда Microsoft XNA имеет класс Vector2, в котором используются числа с плавающей точкой. Это было бы моей самой главной причиной, по которой я бы хотел путешествовать на поплавках, поскольку я верю, что мудрость и опыт команды XNA намного больше моей.
Мне было довольно интересно прочитать ответ на этот вопрос переполнения стека: «Float vs Double Performance» . Существует также ветка gamedev.net с обсуждением двойной производительности графических процессоров. Я думаю, можно с уверенностью предположить, что двойные значения медленнее, чем числа с плавающей точкой, по крайней мере, во многих графических процессорах, и я лично всегда использовал функции OpenGL с плавающей точкой над их двойными аналогами. Это может не применяться в настоящее время, но если вы считаете, что не у всех, кто запускает вашу игру, есть новейший графический процессор с собственной двойной поддержкой, я думаю, что это является достаточной причиной для использования поплавков и повышения производительности.
источник