Vector3 vs. Vector2 - производительность, использование?

8

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

Вместо того, чтобы иметь Vector2для моих позиций, я теперь использую Vector3, исключительно, чтобы использовать его в Zкачестве глубины слоя. Однако, поскольку вы не можете использовать операторы между Vector2и Vector3по какой-то неизвестной причине [1] , я закончил тем, что изменил все другие Vector2s в моей игре, такие как ускорение , скорость и смещение , так что я могу делать вещи, как position += offsetбез ошибок.

Я также изменил свою переменную вращения с floatна Vector3, и я использую Zзначение, чтобы вращать мои текстуры. Я планирую использовать Xи Yмасштабировать мои текстуры, чтобы вы получили эффект Super Paper Mario.

Однако, после изменения всех этих Vector2s в Vector3s, я немного расстроился из-за этого. Как это влияет на производительность игр? Я знаю, что мне не нужно беспокоиться о производительности в моей маленькой платформерной игре, но мне просто интересно.

Есть ли какая - либо заметная производительность между Vector2s- и Vector3с, например , при добавлении или умножая их, или при вызове Normalize, Transformили Distance?


[1] Просто дополнительный вопрос, почему нет операторов для вычислений между Vector3 и Vector2?

Rudey
источник

Ответы:

13

Есть ли какая - либо заметная производительность между Vector2s- и Vector3с, например , при добавлении или умножая их, или при вызове Normalize, Transformили Distance?

Да, у вас есть еще одна координата, поэтому вы будете использовать больше циклов ЦП.

Но маловероятно, что это когда-либо доставит вам неприятности. XNA 4 использует SIMD-расширения для векторной математики (EDIT: только на Windows Phone ), поэтому реализация очень оптимальна (на этой платформе). За исключением случаев, когда вы занимаетесь очень тяжелыми вычислениями, это вряд ли когда-либо вызовет у вас проблемы. Вам нужны Vector3s для ваших позиций, потому что вы сейчас делаете 3D (или 2.5D ...), поэтому, пожалуйста, не делайте преждевременной оптимизации. Это 97% зла 1 .

Просто побочный вопрос, почему нет операторов для вычислений между Vector3 и Vector2?

Потому что это не имеет смысла, математически. Что вы ожидаете получить от таких расчетов? Например, что должно произойти, если вы попытаетесь добавить a Vector3и a Vector2:

[ x1, y1, z1 ] + [ x2, y2 ] = [ x1 + x2, y1 + y2, z1 ] или [ x1, y1 + x2, z1 + y2 ]?

В этом случае вам, как правило, нужно самостоятельно определить, что вы хотите использовать в качестве третьей координаты Vector2, и где вы хотите добавить ее. Например, это решает двусмысленность:

[ x1, y1, z1 ] + [ x2, y2, 0 ] = [ x1 + x2, y1 + y2, z1 ]


Теперь возможно, что некоторые части вашего игрового процесса работают только в 2D. Если есть случаи, когда вам нужны только 2D-координаты, и если вычисления действительно становятся тяжелыми (например, 2D-физика), вы можете придерживаться Vector2s в этой конкретной части кода, чтобы сохранить некоторые драгоценные циклы. Затем вы можете легко переключаться между 2D и 3D координатами, когда вам нужно (например, получить положение сцены из 2D физической позиции или наоборот):

Например , от Vector2с Vector3помощью этого конструктора :

Vector2 v2;
Vector3 v3(v2, someDepthValue);

Или от Vector3до Vector2использования этого конструктора ;

Vector3 v3;
Vector2 v2(v3.X, v3.Y);

1 По словам Дональда Кнута :

Программисты тратят огромное количество времени на размышления или беспокойство по поводу скорости некритических частей своих программ, и эти попытки повышения эффективности на самом деле оказывают сильное негативное влияние при рассмотрении вопросов отладки и обслуживания. Мы должны забыть о малой эффективности, скажем, в 97% случаев: преждевременная оптимизация - корень всего зла . Однако мы не должны упускать наши возможности в эти критические 3%.

Лоран Кувиду
источник
Как я уже сказал, я знаю, что мне не нужно беспокоиться о производительности так скоро, но только мое любопытство заставило меня опубликовать этот вопрос. Я полагаю, вы правы насчет двусмысленности . Спасибо за четкий ответ :)
Rudey
@RuudLenders Я добавил подробности о том, как вы можете действовать, если у вас возникнут проблемы с производительностью.
Лоран Кувиду
Я отредактировал ваш ответ, включив в него очень важный момент: SIMD используется только XNA на Windows Phone! Среда выполнения .NET на ПК - и, следовательно, сама XNA - не поддерживает SIMD. Эквивалент также не поддерживается на Xbox 360.
Эндрю Рассел
(На ПК и Xbox 360 понимание производительности XNA Framework по-прежнему остается применимым руководством для оптимизации ваших векторных операций.)
Эндрю Рассел
Преждевременная оптимизация не является злом. Только бесполезная преждевременная оптимизация есть. Вы должны исключить это из соображений бесполезности , а не из-за преждевременности.
Сэм Хоцевар
3

Вы пытаетесь оптимизировать преждевременно. Большинство упомянутых вами операций (нормализация, преобразование, расстояние) в значительной степени идентичны тем, что делает vector2D, если вы посмотрите на их код, вы заметите, что они практически одинаковы. Единственное отличие состоит в том, что vector3D имеет третью ось. По производительности это должно быть тривиально по сравнению с Vector2D.

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

Sidar
источник
1

Одним из самых значительных эффектов, связанных с использованием Vector3без необходимости, Vector2является увеличение размера на 50% и влияние на кэш .

Эти ненужные дополнительные данные должны быть загружены в кэш процессора из основной памяти. Это sloooow .

Кроме того, загружая эти ненужные данные, вы увеличиваете вероятность того, что вы выталкиваете полезные данные, которые затем немедленно должны быть загружены обратно в кэш.

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

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

v1.X += v2.X; v1.Y += v2.Y;

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

Эндрю Рассел
источник
Таким образом, ручное наложение все еще является самым быстрым способом даже с добавленной поддержкой SIMD?
Микаэль Хогстрем
1
@ MikaelHögström SIMD это почти наверняка будет быстрее - но это только доступно на телефонной платформе Windows , (см правку и замечания , которые я сделал в ответ Лорана Couvidou в).
Эндрю Рассел