Vector3 vs. Vector2 - desempenho, uso?

8

Atualmente, estou brincando com o XNA e criando um simples jogo de plataformas 2D. Eu estava pensando em adicionar várias camadas para torná-lo um pouco desafiador.

Em vez de ter um Vector2para minhas posições, agora uso um Vector3, apenas para usá-lo Zcomo profundidade da camada. No entanto, como você não pode usar operadores entre Vector2e Vector3por algum motivo desconhecido [1] , acabei alterando todos os outros Vector2s no meu jogo, como aceleração , velocidade e deslocamento , para que eu possa fazer coisas como position += offsetsem erros.

Também alterei minha variável de rotação de floatpara Vector3e uso o Zvalor para girar minhas texturas. Estou planejando usar Xe Ymudar minhas texturas para que você obtenha o efeito Super Paper Mario.

No entanto, depois de alterar todos esses Vector2s em Vector3s, me senti um pouco mal com isso. Como isso afeta o desempenho dos jogos? Eu sei que não deveria ter que me preocupar com o desempenho no meu pequeno jogo de plataforma, mas estou curioso.

Existe algum desempenho notável entre Vector2s e Vector3s, por exemplo, quando adicionando ou multiplicando-os, ou ao chamar Normalize, Transformou Distance?


[1] Apenas uma pergunta secundária, por que não existem operadores para cálculos entre o Vector3 e o Vector2?

Rudey
fonte

Respostas:

13

Existe algum desempenho notável entre Vector2s e Vector3s, por exemplo, quando adicionando ou multiplicando-os, ou ao chamar Normalize, Transformou Distance?

Sim, você tem mais uma coordenada para usar mais ciclos da CPU.

Mas é muito improvável que isso lhe cause algum problema. O XNA 4 está usando extensões SIMD para matemática vetorial (EDIT: apenas no Windows Phone ), portanto, a implementação é muito ótima (nessa plataforma). Exceto se você estiver fazendo uma computação muito pesada, é muito improvável que isso lhe cause problemas. Você precisa de Vector3s para suas posições porque agora está fazendo 3D (ou 2.5D ...), portanto, não faça nenhuma otimização prematura. Isso é 97% mau 1 .

Apenas uma pergunta secundária: por que não existem operadores para cálculos entre o Vector3 e o Vector2?

Porque não faz sentido, matematicamente. O que você esperaria sair desses cálculos? Por exemplo, o que deve acontecer se você tentar adicionar ae Vector3a Vector2:

[ x1, y1, z1 ] + [ x2, y2 ] = [ x1 + x2, y1 + y2, z1 ] ou [ x1, y1 + x2, z1 + y2 ]?

Nesse caso, você normalmente precisará determinar por si mesmo o que deseja como terceira coordenada para Vector2e onde deseja adicioná-lo. Por exemplo, isso resolve a ambiguidade:

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


Agora é possível que algumas partes da sua jogabilidade funcionem apenas em 2D. Se há casos em que você só precisa de coordenadas 2D, e se a computação faz ficar muito pesado (por exemplo, física 2D), você pode furar a Vector2s em que parte específica do código para salvar alguns ciclos preciosos. Você pode alternar facilmente entre as coordenadas 2D e 3D quando precisar (por exemplo, obter uma posição de cena a partir de uma posição de física 2D ou o contrário):

Por exemplo, de Vector2para Vector3usar este construtor :

Vector2 v2;
Vector3 v3(v2, someDepthValue);

Ou a partir Vector3de Vector2usar esse construtor ;

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

1 Nas palavras de Donald Knuth :

Os programadores perdem muito tempo pensando ou se preocupando com a velocidade das partes não críticas de seus programas, e essas tentativas de eficiência têm um forte impacto negativo quando são consideradas a depuração e a manutenção. Devemos esquecer as pequenas eficiências, digamos, 97% das vezes: a otimização prematura é a raiz de todo mal . No entanto, não devemos desperdiçar nossas oportunidades nesses 3% críticos.

Laurent Couvidou
fonte
Como eu disse, sei que não preciso me preocupar com desempenho tão cedo, mas foi apenas a minha curiosidade que me fez postar essa pergunta. Eu acho que você está certo sobre a ambiguidade . Obrigado pela resposta clara :)
Rudey
@RuudLenders Adicionei detalhes de como você poderia proceder se algum dia enfrentar problemas de desempenho.
Laurent Couvidou
Editei sua resposta para incluir um ponto muito importante: o SIMD é usado apenas pelo XNA no Windows Phone! O tempo de execução do .NET no PC - e, portanto, o próprio XNA - não suporta SIMD. O equivalente também não é compatível com Xbox 360.
Andrew Russell
(On PC e Xbox 360, Entendimento XNA Framework desempenho ainda é o guia aplicável para otimizar suas operações de vetor.)
Andrew Russell
Otimização prematura não é má. Somente a otimização prematura inútil é. Você precisa descartá-lo por ser inútil , não por ser prematuro.
sam hocevar 26/01
3

Você está tentando otimizar prematuramente. A maioria das operações que você mencionou (normalizar, transformar, distância) são praticamente idênticas às do vetor2D; se você puder ver o código delas, perceberá que elas são praticamente as mesmas. A única diferença é que o vector3D tem um terceiro eixo. Em termos de desempenho, deve ser trivial em comparação com um Vector2D.

Quanto à sua pergunta paralela:
Como você não pode multiplicar matrizes / vetores de linha / vetores de coluna com tamanhos diferentes.

Sidar
fonte
1

Um dos maiores efeitos de desempenho do uso Vector3desnecessário, em vez de Vector2, é o aumento de 50% no tamanho e o efeito que afeta o cache .

Esses dados extras desnecessários precisam ser carregados no cache da CPU a partir da memória principal. Isso é sloooow .

Além disso, ao carregar esses dados desnecessários, você aumenta a chance de enviar dados úteis que precisam ser carregados imediatamente de volta ao cache.

Em um loop modesto, os efeitos do cache sobrecarregam os efeitos da CPU de operações extras.

Além disso, é mais rápido adicionar os elementos diretamente (devido a várias peculiaridades do .NET). Portanto, se você estiver otimizando micro, não utilizará as operações vetoriais. Portanto, se você precisar adicionar apenas os dois primeiros elementos de um vetor, faça o seguinte:

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

Mas esses tipos de considerações de desempenho são realmente aplicáveis ​​apenas a coisas como motores de partículas, motores de física etc. Então não se preocupe demais!

Andrew Russell
fonte
Então o alinhamento manual ainda é o caminho mais rápido, mesmo com o suporte adicional do SIMD?
Mikael Högström
11
@ MikaelHögström SIMD é quase certo que vai ser mais rápido - mas é única disponíveis na plataforma Windows Phone (ver a edição e comentários que fiz a resposta de Laurent Couvidou).
Andrew Russell