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

Estoy pensando en términos de relleno de compilador, ¿hay alguna manera de que pueda hacer que el tamaño de (nodea) sea menor que 16?¿Cuál es el tamaño más pequeño que puedo hacer de esta estructura en una máquina de 64 bits?

+0

Creo que con el embalaje apretado, que va a terminar con 8 bytes para el puntero y 2 bytes para los personajes ... pero no 100% seguro. Mire #pragmas para su compilador que afecta el empaque de la estructura, elija el que proporcione el embalaje más ajustado y pruebe sizeof(). –

+0

¿En qué plataforma, 32 bits o 64 bits, qué compilador (versión)? –

Respuesta

5

Usted puede usar la directiva #pragma pack compilador 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

Olvidé mencionar, estoy usando gcc – jck

+0

Debe ser casi idéntico en gcc. Consulte http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html –

+3

Recuerde que el uso de esta estructura para una lista vinculada disminuiría el rendimiento general de la lista, ya que la dirección del siguiente nodo no está alineada . Intenta colocar el 'struct node * next' como primer elemento de la estructura.Por lo tanto, la dirección siempre se alinearía y se puede buscar en una instrucción/ciclos alquilados posibles. – DipSwitch

4

Puede que sea 10 bytes si pack que, siempre que el hardware subyacente no tiene ningún requisito de alineación particulares. Tenga en cuenta que una vez que comienza a empacar, deja atrás la portabilidad.

Cómo afectar el embalaje depende de su compilador pero la mayoría de los compiladores, incluido gcc, admiten directivas de tipo #pragma pack.

5

A menos que sea algo poco convencional, se puede empaquetar en 1 + 1 + 8 = 10 bytes. Si los punteros deben estar alineados, entonces 16 bytes. Si coloca primero el puntero y luego los caracteres, luego 10 bytes, pero los requisitos de alineación aún pueden ser 16 cuando se hace una matriz de estas estructuras.

1

Esto depende del compilador. Por lo general, puede controlar la alineación de los campos/variables de la estructura. Por ejemplo, con gcc podría utilizar

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

para obtener 10 para sizeof(nodea) en la plataforma de 64 bits.

+0

Siempre empaque la estructura completa y no solo una variable en la estructura. 'typedef struct __attribute__ ((packed)) node {...' – DipSwitch

+0

Fue solo un ejemplo de [documentación de GNU] (http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html). Y "siempre" todo depende de la tarea, ¿no es así? –

+0

Normalmente empacarías toda la estructura, ya que es más fácil de leer. Además, es más difícil predecir el tamaño de la estructura (alguien debería pensar más) para impedir el tamaño final de la estructura. Además, si agrega un char después de la entrada del nodo, esto nuevamente usaría 8 bytes para ese único carácter, ya que este es el tamaño de palabra del procesador. Lo que también podría conducir a un comportamiento conductual indefinido si, por ejemplo, desea leer un archivo de datos almacenados que se ha generado en una arquitectura de 64 bits y se lee en una arquitectura de 32 bits. – DipSwitch

0

El uso empaquetado en una estructura también significa que el compilador no puede reordenar la estructura de datos; en algunas plataformas, el embalaje puede tener una gran disminución del rendimiento. Algunos procesadores no pueden obtener palabras desalineadas, de modo que si el código se compila en esa plataforma, el compilador se vería obligado a obtener la palabra por byte y cambiar todo en el lugar correcto, esto es definitivamente algo que no desea. Especialmente no en una lista enlazada, ya que esto haría que tu lista realmente fuera muy lenta de acceder ... E incluso si la CPU admite la obtención de unaligned, la CPU necesitaría hacer ciclos extra para leer desde 2 direcciones en memoria y reconectarlas de nuevo.

Es por eso que debe ver cómo puede ayudar al compilador. Te gustaría que struct esté alineado con las palabras para que la dirección del próximo nodo siempre pueda leerse con una sola instrucción de lectura. Esto significaría para una arquitectura de 64 bits que desea colocar el puntero del siguiente nodo en la parte superior para que siempre esté alineado, a continuación, desea asegurarse de que si utiliza las estructuras en una matriz, la dirección de struct node * siempre será alineado, por lo que debe asegurarse de que su tamaño de estructura final sea un múltiplo de 8 bytes. Esto significa que puede agregar 6 elementos más o puede elegir un tipo de datos más grande.

Esto significaría que se obtendría algo como esto:

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; 

etc etc etc

Cuestiones relacionadas