Nel libro Game Coding Complete, 3rd Edition, l'autore cita una tecnica per ridurre le dimensioni della struttura dati e aumentare le prestazioni di accesso. In sostanza si basa sul fatto che ottieni prestazioni quando le variabili membro sono allineate in memoria. Si tratta di un'eventuale potenziale ottimizzazione da cui i compilatori potrebbero trarre vantaggio, ma assicurandosi che ogni variabile sia allineata finiscono per gonfiare le dimensioni della struttura dei dati.Allineamento bit per aumenti di spazio e prestazioni
O quella era la sua richiesta almeno.
Il vero aumento delle prestazioni, afferma, è utilizzando il cervello e assicurando che la struttura sia progettata correttamente per sfruttare gli aumenti di velocità e impedire al compilatore di gonfiarsi. Egli fornisce il seguente frammento di codice:
#pragma pack(push, 1)
struct SlowStruct
{
char c;
__int64 a;
int b;
char d;
};
struct FastStruct
{
__int64 a;
int b;
char c;
char d;
char unused[ 2 ]; // fill to 8-byte boundary for array use
};
#pragma pack(pop)
Utilizzando i suddetti struct
oggetti in un test non specificato che segnala un aumento delle prestazioni di 15.6%
(222ms
rispetto al 192ms
) ed una dimensione più piccola per il FastStruct
. Questo rende ogni senso su carta per me, ma non riesce a tenere sotto il mio test:
stesso tempo risulta e dimensioni (contando per il char unused[ 2 ]
)!
Ora, se il #pragma pack(push, 1)
è isolato solo per FastStruct
(o rimossi del tutto) facciamo vedere una differenza:
Così, finalmente, qui sta il problema: Do compilatori moderni (VS2010 in particolare) già ottimizzare per l'allineamento dei bit, quindi la mancanza di aumento delle prestazioni (ma aumentare le dimensioni della struttura come un effetto collaterale, come affermato da Mike Mcshaffry)? Oppure il mio test non è abbastanza intenso/inconcludente per restituire risultati significativi?
Per i test ho eseguito una serie di attività da operazioni matematiche, allineamento/controllo di array multidimensionali su colonna principale, operazioni con matrici, ecc. Sul membro non allineato __int64
. Nessuno dei quali ha prodotto risultati diversi per entrambe le strutture.
Alla fine, anche se il loro è stato un aumento delle prestazioni, questo è ancora un bocconcino utile da tenere a mente per mantenere l'utilizzo della memoria al minimo. Ma mi piacerebbe se ci fosse un aumento delle prestazioni (non importa quanto minore) che io non sto vedendo.
Il fatto che si ottenga esattamente lo stesso tempo per tutti i test suggerisce che non si corre abbastanza a lungo. La risoluzione del codice temporale non è probabilmente abbastanza alta da mostrare differenze. –
Forse durante i test la variabile in questione è stata utilizzata così tanto da essere memorizzata nella cache di un registro. Avere una variabile int64 attraversa un limite di memoria dove richiederebbe che DUE istruzioni di assemblaggio per recuperarlo sarebbero necessariamente più lente. –
@BoPersson: Più probabilmente, il compilatore li ha semplicemente ottimizzati per produrre lo stesso codice. – Puppy