Vector3 vs. Vector2: ¿rendimiento, uso?

8

Actualmente estoy jugando con XNA y creando un simple juego de plataformas en 2D. Estaba pensando en agregar varias capas para que sea un poco desafiante.

En lugar de tener un Vector2para mis posiciones, ahora uso un Vector3, solo para usarlo Zcomo profundidad de capa. Sin embargo, dado que no puedes usar operadores entre Vector2y Vector3por alguna razón desconocida [1] , terminé cambiando todos los demás Vector2s en mi juego, como la aceleración , la velocidad y el desplazamiento , por lo que puedo hacer cosas como position += offsetsin errores.

También cambié mi variable de rotación de floata Vector3, y uso el Zvalor para rotar mis texturas. Estoy planeando usar Xy Yvoltear mis texturas a escala, para que obtengas el efecto Super Paper Mario.

Sin embargo, después de cambiar todas estas Vector2s en Vector3s, me sentí un poco mal por eso. ¿Cómo afecta esto el rendimiento de los juegos? Sé que no debería tener que preocuparme por el rendimiento en mi pequeño juego de plataformas, pero tengo curiosidad por eso.

¿Hay alguna rendimiento notable entre Vector2s y Vector3s, por ejemplo, al añadir o multiplicándolos, o al llamar Normalize, Transformo Distance?


[1] Solo una pregunta secundaria, ¿por qué no hay operadores para los cálculos entre Vector3 y Vector2?

Rudey
fuente

Respuestas:

13

¿Hay alguna rendimiento notable entre Vector2s y Vector3s, por ejemplo, al añadir o multiplicándolos, o al llamar Normalize, Transformo Distance?

Sí, tiene una coordenada más, por lo que utilizará más ciclos de CPU.

Pero es muy poco probable que alguna vez te dé algún problema. XNA 4 está utilizando extensiones SIMD para matemáticas vectoriales (EDITAR: solo en Windows Phone ), por lo que la implementación es muy óptima (en esa plataforma). Excepto si estás haciendo computación muy pesada, es muy poco probable que te cause problemas. Necesitas Vector3s para tus posiciones porque ahora estás haciendo 3D (o 2.5D ...), así que no hagas ninguna optimización prematura. Esto es 97% malvado 1 .

Solo una pregunta secundaria, ¿por qué no hay operadores para los cálculos entre Vector3 y Vector2?

Porque no tiene sentido, matemáticamente. ¿Qué esperarías de esos cálculos? Por ejemplo lo que debería ocurrir si se intenta añadir un Vector3y una Vector2:

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

En este caso, normalmente necesitará determinar usted mismo qué desea como una tercera coordenada para el lugar Vector2y dónde desea agregarlo. Por ejemplo, esto resuelve la ambigüedad:

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


Ahora es posible que algunas partes de tu juego funcionen solo en 2D. Si hay casos en los que solo necesita coordenadas 2D, y si la informática se vuelve realmente pesada (por ejemplo, física 2D), puede apegarse a Vector2s en esa parte específica del código para guardar algunos ciclos preciosos. Luego puede cambiar fácilmente entre coordenadas 2D y 3D cuando lo necesite (por ejemplo, obtener una posición de escena desde una posición física 2D o al revés):

Por ejemplo, de Vector2que Vector3el uso de este constructor :

Vector2 v2;
Vector3 v3(v2, someDepthValue);

O desde Vector3que Vector2el uso de ese constructor ;

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

1 En palabras de Donald Knuth :

Los programadores pierden enormes cantidades de tiempo pensando o preocupándose por la velocidad de las partes no críticas de sus programas, y estos intentos de eficiencia en realidad tienen un fuerte impacto negativo cuando se consideran la depuración y el mantenimiento. Deberíamos olvidarnos de las pequeñas eficiencias, digamos alrededor del 97% del tiempo: la optimización prematura es la raíz de todo mal . Sin embargo, no debemos dejar pasar nuestras oportunidades en ese crítico 3%.

Laurent Couvidou
fuente
Como dije, sé que no tengo que preocuparme por el rendimiento tan pronto, pero fue solo mi curiosidad lo que me hizo publicar esta pregunta. Supongo que tienes razón sobre la ambigüedad . Gracias por la respuesta clara :)
Rudey
@RuudLenders He agregado detalles sobre cómo podría proceder si alguna vez enfrenta problemas de rendimiento.
Laurent Couvidou
He editado su respuesta para incluir un punto muy importante: ¡SIMNA solo lo usa XNA en Windows Phone! El tiempo de ejecución de .NET en PC, y por lo tanto XNA, no es compatible con SIMD. El equivalente tampoco es compatible con Xbox 360.
Andrew Russell
(En PC y Xbox 360, Comprender el rendimiento del marco XNA sigue siendo la guía aplicable para optimizar sus operaciones vectoriales)
Andrew Russell
La optimización prematura no es mala. Solo es inútil la optimización prematura. Debe descartarlo por ser inútil , no por ser prematuro.
sam hocevar
3

Estás tratando de optimizar prematuramente. La mayoría de las operaciones que mencionó (normalizar, transformar, distancia) son prácticamente idénticas a las que hace vector2D, si puede ver su código, notará que son prácticamente iguales. La única diferencia es que vector3D tiene un tercer eje. En cuanto al rendimiento, debería ser trivial en comparación con un Vector2D.

En cuanto a su pregunta paralela:
porque no puede multiplicar matrices / vectores de fila / vectores de columna que tienen dos tamaños diferentes.

Sidar
fuente
1

Uno de los mayores efectos de rendimiento del uso Vector3innecesario, en lugar de Vector2, es el aumento del 50% en el tamaño y el efecto que tiene en la memoria caché .

Es necesario cargar esos datos adicionales innecesarios en la memoria caché de la CPU desde la memoria principal. Esto es muy lento .

Además, al cargar estos datos innecesarios, aumenta la posibilidad de que esté sacando datos útiles que inmediatamente deben volver a cargarse en la memoria caché.

En un bucle modestamente ajustado, los efectos de caché abrumarán cualquier efecto de CPU de realizar operaciones adicionales.

Además, es más rápido agregar los elementos directamente (debido a varias peculiaridades de .NET). Entonces, si está micro optimizando, no utilizará las operaciones vectoriales de todos modos. Entonces, si solo necesita agregar los dos primeros elementos de un vector, puede hacer esto:

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

Pero este tipo de consideraciones de rendimiento solo son realmente aplicables a cosas como motores de partículas, motores de física, etc. ¡Así que no te preocupes demasiado!

Andrew Russell
fuente
Entonces, ¿la alineación manual sigue siendo la forma más rápida de hacerlo, incluso con el soporte adicional de SIMD?
Mikael Högström
1
@ MikaelHögström SIMD es casi seguro que va a ser más rápido - pero es solamente disponible en la plataforma Windows Phone (ver la edición y los comentarios que hice a la respuesta de Laurent Couvidou).
Andrew Russell