2011-11-30 12 views
5
typedef struct node{ 
    char one; 
    char two; 
    struct node *next; 
} nodea; 

Sto pensando in termini di riempimento del compilatore, c'è un modo per rendere la dimensione di (nodea) inferiore a 16?Qual è la dimensione più piccola che posso rendere questa struttura su una macchina a 64 bit?

+0

Penso che con più stretto imballaggio, si ritroverà con 8 byte per il puntatore e 2 byte per i personaggi ... ma non sicuro al 100%. Esamina #pragmas per il tuo compilatore che influisce sulla struttura della struttura, scegli quella che fornisce l'imballaggio più stretto e prova sizeof(). –

+0

Su quale piattaforma, 32 bit o 64 bit, quale compilatore (versione)? –

risposta

5

È possibile utilizzare la direttiva #pragma pack compilatore http://msdn.microsoft.com/en-us/library/2e70t5y1%28v=vs.80%29.aspx

#pragma pack(push) 
#pragma pack(1) 
typedef struct node { 
    char one; 
    char two; 
    struct node* next; 
} nodea; 
#pragma pack(pop) 
+0

Ho dimenticato di menzionare, sto usando gcc – jck

+0

Dovrebbe essere quasi identico su gcc. Vedi http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html –

+3

Ricorda che l'utilizzo di questa struttura per un elenco collegato ridurrebbe le prestazioni generali dell'elenco, poiché l'indirizzo del nodo successivo non è allineato . Prova a posizionare il 'struct node * next' come primo elemento della struct.Quindi l'indirizzo sarebbe sempre allineato e può essere recuperato in una istruzione/cicli disponibili. – DipSwitch

4

Si può rendere 10 byte se si pack che, assumendo l'hardware sottostante non ha requisiti di allineamento particolari. Sii consapevole del fatto che una volta che inizi a fare i bagagli lascerai indietro la portabilità.

Come influenzare l'imballaggio dipende dal compilatore ma la maggior parte dei compilatori, incluso gcc, supporta le direttive di tipo #pragma pack.

5

A meno che non sia qualcosa di non convenzionale, può essere impacchettato in 1 + 1 + 8 = 10 byte. Se i puntatori devono essere allineati, quindi 16 byte. Se metti prima il puntatore e il carattere successivo, allora 10 byte, ma i requisiti di allineamento potrebbero ancora renderlo 16 quando crei un array di queste strutture.

1

Questo dipende dal compilatore. Di solito è possibile controllare l'allineamento dei campi/variabili della struttura. Ad esempio, con gcc è possibile utilizzare

typedef struct __attribute__ ((packed)) node { 
    char one; 
    char two; 
    struct node *next; 
} nodea; 

per ottenere 10 per sizeof(nodea) su piattaforma a 64 bit.

+0

Imballare sempre l'intera struttura e non solo una variabile nella struttura. 'typedef struct __attribute__ ((packed)) node {...' – DipSwitch

+0

Era solo un esempio di [documentazione GNU] (http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html). E "sempre" tutto dipende dal compito, non è vero? –

+0

Normalmente si impacchetta l'intera struct poiché è più facile da leggere. Inoltre è più difficile prevedere la dimensione della struttura (qualcuno dovrebbe pensare più duramente) per separare la dimensione della struttura finale. Inoltre, se aggiungi un char dopo la voce del nodo, questo utilizzerà ancora 8 byte per quel singolo carattere, poiché questa è la dimensione della parola del processore. Il che potrebbe portare anche a un comportamento non definito se ad esempio si desidera leggere un file di dati memorizzati che è stato generato su un'architettura a 64 bit e viene letto su un'architettura a 32 bit. – DipSwitch

0

L'utilizzo del pacchetto su una struttura implicherebbe anche che il compilatore non possa riordinare la struttura dei dati, in alcune piattaforme l'imballaggio può ridurre notevolmente le prestazioni. Alcuni processori non possono ottenere parole non allineate, quindi se il codice sarebbe stato compilato su quella piattaforma il compilatore sarebbe costretto a ottenere la parola per byte e spostare tutto nel posto giusto, questo è sicuramente qualcosa che non vuoi. Soprattutto non su una lista concatenata poiché ciò renderebbe davvero molto lenta l'accesso alla tua lista ... E anche se la CPU supporta i non allineati, la CPU avrebbe bisogno di fare cicli extra per leggere da 2 indirizzi in memoria e concatenarli di nuovo.

Questo è il motivo per cui è necessario considerare come è possibile aiutare il compilatore. Vorrai che struct sia allineato alla parola in modo che l'indirizzo del prossimo nodo possa sempre essere letto con una singola istruzione di lettura. Ciò significherebbe per un'architettura a 64 bit che si desidera posizionare il puntatore del nodo successivo in cima in modo che questo sia sempre allineato, quindi si vorrebbe assicurarsi che se si utilizza la struttura in un array l'indirizzo di struct node * sia sempre allineato, quindi è necessario assicurarsi che la dimensione della struttura finale sia un multiplo di 8 byte. Ciò significherebbe che puoi aggiungere altri 6 elementi o puoi scegliere un tipo di dati più grande.

Ciò significa che si otterrebbe qualcosa di simile:

typedef struct __attribute__((packed)) node { 
    struct node *next; 
    char data[8]; 
} nodea; 

typedef struct __attribute__((packed)) node { 
    struct node *next; 
    uint16_t data[4]; 
} nodea; 

typedef struct __attribute__((packed)) node { 
    struct node *next; 
    uint32_t data[2]; 
} nodea; 

ecc ecc ecc

Problemi correlati