Vector3 vs. Vector2 - prestazioni, utilizzo?


8

Attualmente sto giocando con XNA e sto creando un semplice platform 2D. Stavo pensando di aggiungere più livelli per renderlo un po 'difficile.

Invece di avere a Vector2per le mie posizioni, ora uso a Vector3, solo per usarlo Zcome profondità del livello. Tuttavia, poiché non è possibile utilizzare gli operatori tra Vector2e Vector3per qualche motivo sconosciuto [1] , ho finito per cambiare tutte le altre Vector2s nel mio gioco, come accelerazione , velocità e offset , quindi posso fare cose come position += offsetsenza errori.

Ho anche cambiato la mia variabile di rotazione da floata Vector3, e uso il Zvalore per ruotare le mie trame. Sto progettando di usare Xe Yper ridimensionare le mie trame in modo da ottenere l'effetto Super Paper Mario.

Tuttavia, dopo aver cambiato tutti questi Vector2s in Vector3s, mi sentivo un po 'in colpa. In che modo ciò influisce sulle prestazioni dei giochi? So che non dovrei preoccuparmi delle prestazioni nel mio piccolo gioco platform, ma sono solo curioso.

C'è qualche prestazione notevole fra Vector2s e Vector3s, ad esempio quando si aggiungono o moltiplicandoli, o quando si chiama Normalize, Transformo Distance?


[1] Solo una domanda a margine, perché non ci sono operatori per i calcoli tra Vector3 e Vector2?

Risposte:


13

C'è qualche prestazione notevole fra Vector2s e Vector3s, ad esempio quando si aggiungono o moltiplicandoli, o quando si chiama Normalize, Transformo Distance?

Sì, hai un'altra coordinata in modo da utilizzare più cicli della CPU.

Ma è molto improbabile che ti dia mai problemi. XNA 4 utilizza estensioni SIMD per la matematica vettoriale (EDIT: solo su Windows Phone ), quindi l'implementazione è molto ottimale (su quella piattaforma). Tranne se stai facendo un calcolo molto pesante, è molto improbabile che ti causi mai problemi. Hai bisogno di Vector3s per le tue posizioni perché ora stai facendo 3D (o 2.5D ...), quindi per favore non fare alcuna ottimizzazione prematura. Questo è il 97% di male 1 .

Solo una domanda a margine, perché non ci sono operatori per i calcoli tra Vector3 e Vector2?

Perché non ha senso, matematicamente. Cosa ti aspetti che esca da tali calcoli? Ad esempio cosa dovrebbe succedere se provi ad aggiungere a Vector3e a Vector2:

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

In questo caso, in genere è necessario determinare da soli ciò che si desidera come terza coordinata per Vector2e dove si desidera aggiungerlo. Ad esempio, questo risolve l'ambiguità:

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


Ora è possibile che alcune parti del tuo gameplay funzionino solo in 2D. Se ci sono casi nei quali è sufficiente 2D coordinate, e se il calcolo lo fa diventare davvero pesante (ad esempio, la fisica 2D), è possibile attenersi a Vector2s in quella parte specifica del codice per salvare alcuni cicli preziosi. È quindi possibile passare facilmente tra le coordinate 2D e 3D quando è necessario (ad esempio ottenere una posizione della scena da una posizione fisica 2D o viceversa):

Ad esempio, da Vector2a Vector3utilizzare questo costruttore :

Vector2 v2;
Vector3 v3(v2, someDepthValue);

O da Vector3a Vector2utilizzare quel costruttore ;

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

1 Nelle parole di Donald Knuth :

I programmatori sprecano enormi quantità di tempo pensando o preoccupandosi della velocità delle parti non critiche dei loro programmi e questi tentativi di efficienza hanno effettivamente un forte impatto negativo quando si considerano il debug e la manutenzione. Dobbiamo dimenticare le piccole efficienze, diciamo circa il 97% delle volte: l'ottimizzazione prematura è la radice di tutti i mali . Eppure non dovremmo rinunciare alle nostre opportunità in quel 3% critico.


Come ho detto, so che non devo preoccuparmi delle prestazioni così presto, ma è stata solo la mia curiosità a farmi pubblicare questa domanda. Immagino tu abbia ragione sull'ambiguità . Grazie per la chiara risposta :)
Rudey,

@RuudLenders Ho aggiunto dettagli su come procedere in caso di problemi di prestazioni.
Laurent Couvidou,

Ho modificato la tua risposta per includere un punto molto importante: SIMD viene utilizzato solo da XNA su Windows Phone! Il runtime .NET su PC - e quindi XNA stesso - non supporta SIMD. L'equivalente inoltre non è supportato su Xbox 360.
Andrew Russell,

(Su PC e Xbox 360, Comprendere le prestazioni di XNA Framework è ancora la guida applicabile per ottimizzare le operazioni vettoriali.)
Andrew Russell,

L'ottimizzazione prematura non è male. Solo l'ottimizzazione prematura inutile è. Devi escluderlo per il fatto di essere inutile , non per essere prematuro.
Sam Hocevar,

3

Stai cercando di ottimizzare prematuramente. La maggior parte delle operazioni che hai citato (normalizzazione, trasformazione, distanza) sono praticamente identiche a ciò che fa vector2D, se puoi vedere il loro codice noterai che sono praticamente le stesse. L'unica differenza è che vector3D ha un terzo asse. Per quanto riguarda le prestazioni, dovrebbe essere banale rispetto a un Vector2D.

Per quanto riguarda la tua domanda secondaria:
perché non puoi moltiplicare matrici / vettori di riga / vettori di colonna che hanno entrambe dimensioni diverse.


1

Uno dei maggiori effetti sulle prestazioni dell'utilizzo Vector3non necessario, anziché Vector2, è l'aumento del 50% delle dimensioni e l'effetto che ha sulla cache .

I dati extra non necessari devono essere caricati nella cache della CPU dalla memoria principale. Questo è sloooow .

Inoltre, caricando questi dati non necessari, si aumenta la possibilità di inviare dati utili che devono essere immediatamente caricati nuovamente nella cache.

In un ciclo moderatamente stretto, gli effetti della cache travolgeranno qualsiasi effetto CPU derivante da operazioni extra.

Inoltre, è più veloce aggiungere direttamente gli elementi (a causa di varie stranezze di .NET). Quindi, se stai microottimizzando, non utilizzerai comunque le operazioni vettoriali. Quindi, se hai solo bisogno di aggiungere i primi due elementi di un vettore, puoi farlo:

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

Ma questo tipo di considerazioni sulle prestazioni sono realmente applicabili solo a cose come i motori a particelle, i motori fisici e così via. Quindi non preoccuparti troppo!


Quindi l'allineamento manuale è ancora il modo più veloce di procedere anche con il supporto aggiunto di SIMD?
Mikael Högström,

1
@ MikaelHögström Il SIMD sarà quasi sicuramente più veloce, ma è disponibile solo sulla piattaforma Windows Phone (vedi la modifica e i commenti che ho fatto alla risposta di Laurent Couvidou).
Andrew Russell,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.