Vector3 vs Vector2 - performances, utilisation?

8

Je joue actuellement avec XNA et je crée un simple jeu de plateforme 2D. Je pensais ajouter plusieurs couches pour en faire un peu difficile.

Au lieu d'avoir un Vector2pour mes positions, j'utilise maintenant un Vector3, uniquement pour l'utiliser Zcomme profondeur de couche. Cependant, comme vous ne pouvez pas utiliser d'opérateurs entre Vector2et Vector3pour une raison inconnue [1] , j'ai fini par changer tous les autres Vector2s de mon jeu, tels que l' accélération , la vitesse et l' offset , donc je peux faire des choses comme position += offsetsans erreurs.

J'ai également changé ma variable de rotation de floaten Vector3, et j'utilise la Zvaleur pour faire pivoter mes textures. Je prévois d'utiliser le Xet Ypour inverser l'échelle de mes textures, afin d'obtenir l'effet Super Paper Mario.

Cependant, après avoir changé tous ces Vector2s en Vector3s, je me sentais un peu mal à ce sujet. Comment cela affecte-t-il les performances des jeux? Je sais que je ne devrais pas avoir à me soucier des performances de mon petit jeu de plateforme, mais je suis simplement curieux de savoir.

Y at - il des performances notable entre Vector2s et Vector3s, par exemple lors de l' ajout ou de les multiplier, ou lors de l' appel Normalize, Transformou Distance?


[1] Juste une question secondaire, pourquoi n'y a-t-il pas d'opérateurs pour les calculs entre Vector3 et Vector2?

Rudey
la source

Réponses:

13

Y at - il des performances notable entre Vector2s et Vector3s, par exemple lors de l' ajout ou de les multiplier, ou lors de l' appel Normalize, Transformou Distance?

Oui, vous avez une coordonnée de plus, vous utiliserez donc plus de cycles CPU.

Mais il est très peu probable que cela vous cause des problèmes. XNA 4 utilise des extensions SIMD pour les mathématiques vectorielles (EDIT: sur Windows Phone uniquement ), donc l'implémentation est très optimale (sur cette plate-forme). Sauf si vous faites de l'informatique très lourde, il est très peu probable qu'elle vous cause des problèmes. Vous avez besoin de Vector3s pour vos positions parce que vous faites maintenant de la 3D (ou 2.5D ...), alors ne faites pas d'optimisation prématurée. C'est 97% de mal 1 .

Juste une question secondaire, pourquoi n'y a-t-il pas d'opérateurs pour les calculs entre Vector3 et Vector2?

Parce que cela n'a aucun sens, mathématiquement. Qu'attendriez-vous de ces calculs? Par exemple, que devrait-il se passer si vous essayez d'ajouter un Vector3et un Vector2:

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

Dans ce cas, vous devrez généralement déterminer par vous-même ce que vous voulez comme troisième coordonnée Vector2 , et où vous souhaitez l'ajouter. Par exemple, cela résout l'ambiguïté:

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


Il est maintenant possible que certaines parties de votre gameplay ne fonctionnent qu'en 2D. S'il y a des cas où vous avez besoin 2D coordonnées, et si le calcul ne se vraiment lourd (par exemple la physique 2D), vous pouvez coller àVector2 s dans cette partie spécifique du code pour sauver quelques cycles précieux. Vous pouvez ensuite facilement basculer entre les coordonnées 2D et 3D lorsque vous en avez besoin (par exemple, obtenir une position de scène à partir d'une position physique 2D, ou l'inverse):

Par exemple de Vector2à l' Vector3utilisation de ce constructeur :

Vector2 v2;
Vector3 v3(v2, someDepthValue);

Ou de Vector3à l' Vector2aide de ce constructeur ;

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

1 Selon les mots de Donald Knuth :

Les programmeurs perdent énormément de temps à penser ou à s'inquiéter de la vitesse des parties non critiques de leurs programmes, et ces tentatives d'efficacité ont en fait un fort impact négatif lorsque le débogage et la maintenance sont envisagés. Il faut oublier les petites efficacités, disons environ 97% du temps: l' optimisation prématurée est la racine de tout mal . Pourtant, nous ne devons pas laisser passer nos opportunités dans ces 3% critiques.

Laurent Couvidou
la source
Comme je l'ai dit, je sais que je n'ai pas à me soucier des performances si tôt, mais c'est juste ma curiosité qui m'a fait poser cette question. Je suppose que vous avez raison sur l' ambiguïté . Merci pour la réponse claire :)
Rudey
@RuudLenders J'ai ajouté des détails sur la façon de procéder si vous rencontrez des problèmes de performances.
Laurent Couvidou
J'ai modifié votre réponse pour inclure un point très important: SIMD n'est utilisé que par XNA sur Windows Phone! Le runtime .NET sur PC - et donc XNA lui-même - ne prend pas en charge SIMD. L'équivalent n'est pas non plus pris en charge sur Xbox 360.
Andrew Russell
(Sur PC et Xbox 360, Comprendre les performances du framework XNA est toujours le guide applicable pour optimiser vos opérations vectorielles.)
Andrew Russell
L'optimisation prématurée n'est pas mauvaise. Seule une optimisation prématurée inutile est. Vous devez l'exclure au motif d'être inutile , pas au motif d'être prématuré.
sam hocevar
3

Vous essayez d'optimiser prématurément. La plupart des opérations que vous avez mentionnées (normaliser, transformer, distance) sont à peu près identiques à ce que fait vector2D, si vous pouvez regarder leur code, vous remarquerez qu'elles sont pratiquement les mêmes. La seule différence est que vector3D a un troisième axe. En termes de performances, il devrait être trivial par rapport à un Vector2D.

Quant à votre question secondaire:
Parce que vous ne pouvez pas multiplier les matrices / vecteurs de ligne / vecteurs de colonne qui ont tous deux des tailles différentes.

Sidar
la source
1

L'un des plus grands effets sur les performances d'une utilisation Vector3inutile, au lieu de Vector2, est l'augmentation de 50% de la taille et l'effet qui a sur le cache .

Ces données supplémentaires inutiles doivent être chargées dans le cache du processeur à partir de la mémoire principale. C'est lent .

De plus, en chargeant ces données inutiles, vous augmentez les chances que vous extrayiez des données utiles qui doivent ensuite immédiatement être rechargées dans cache.

Dans une boucle modérément serrée, les effets de cache submergeront tous les effets de processeur d'effectuer des opérations supplémentaires.

En outre, il est plus rapide d'ajouter directement les éléments (en raison de diverses bizarreries de .NET). Donc, si vous micro-optimisez, vous n'utiliserez pas les opérations vectorielles de toute façon. Donc, si vous avez seulement besoin d'ajouter les deux premiers éléments d'un vecteur, vous pouvez le faire:

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

Mais ces types de considérations de performances ne sont vraiment applicables qu'à des choses comme les moteurs à particules, les moteurs physiques, etc. Alors ne t'inquiète pas trop!

Andrew Russell
la source
Donc, l'incrustation manuelle est-elle toujours la voie la plus rapide, même avec le support supplémentaire de SIMD?
Mikael Högström
1
@ MikaelHögström SIMD est presque certainement être plus rapide - mais il est uniquement disponible sur la plate - forme Windows Phone (voir l'édition et les commentaires que j'ai fait à la réponse de Laurent Couvidou).
Andrew Russell