2012-04-25 18 views
6

Entiendo el relleno que tiene lugar entre los miembros de una estructura para garantizar la alineación correcta de los tipos individuales. Sin embargo, ¿por qué la estructura de datos tiene que ser un múltiplo de alineación del miembro más grande? No entiendo que el relleno sea necesario al final.por qué el tamaño de la estructura debe ser un múltiplo de la alineación más grande de cualquier miembro de estructura

Referencia: http://en.wikipedia.org/wiki/Data_structure_alignment

Respuesta

7

Buena pregunta. Considere este tipo hipotética:

struct A { 
    int n; 
    bool flag; 
}; 

Por lo tanto, un objeto de tipo A debe tomar cinco bytes (cuatro para el int más uno para el bool), pero en realidad se tarda ocho. ¿Por qué?

La respuesta se ve si se utiliza el tipo de esta manera:

const size_t N = 100; 
A a[N]; 

Si cada A eran sólo cinco bytes, entonces a[0] alinearía pero a[1], a[2] y la mayoría de los otros elementos no lo haría.

Pero, ¿por qué la alineación incluso importa? Hay varias razones, todas relacionadas con el hardware. Una razón es que la memoria utilizada recientemente/recientemente se almacena en caché en líneas de caché en la CPU de silicio para un acceso rápido. Un objeto alineado más pequeño que una línea de caché siempre cabe en una sola línea (pero vea los comentarios interesantes que se adjuntan a continuación), pero un objeto desalineado puede dividirse en dos líneas, desperdiciando el caché.

En realidad, existen razones de hardware aún más fundamentales, que tienen que ver con la forma en que los datos direccionables por byte se transfieren a un bus de datos de 32 o 64 bits, aparte de las líneas de caché. La desalineación no solo obstruirá el bus con extra fetches (debido a que se montará a horcajadas), sino que también obligará a los registros a desplazar bytes a medida que entren. Lo que es peor, la desalineación tiende a confundir la lógica de optimización (al menos, el manual de optimización de Intel dice lo hace, aunque no tengo ningún conocimiento personal de este último punto). Entonces, la desalineación es muy mala desde el punto de vista del rendimiento.

Por lo general, vale la pena desperdiciar los bytes de relleno por estos motivos.

Actualización: Los comentarios a continuación son útiles. Los recomiendo

+1

* Un objeto alineado más pequeño que una línea de caché siempre cabe en una sola línea, pero un objeto desalineado puede dividirse en dos líneas *> ** No **. Ya sea que esté alineado o no, un objeto podría estar a dos líneas. –

+1

@MatthieuM., En realidad sí y no. Los tamaños de línea de caché son múltiplos del tamaño de datos más grande y cualquier otro tipo fundamental. Por lo tanto, todos (er, la mayoría) de los tipos _native_ alineados estarán naturalmente dentro de una sola línea de caché. Tenga en cuenta que cualquier tipo de alineación de 1,2,4,8,16 bytes se alineará automáticamente para ajustarse a una línea de caché de 64 o 128 bytes. Un sistema sería esencialmente inutilizable si este no fuera el caso. –

+1

@ edA-qamort-ora-y: seguro, pero un objeto que es un compuesto de tipos fundamentales podría fácilmente abarcar dos líneas. Incluso si es más pequeño. Suponiendo una línea de 64 bytes, puedo tener un objeto de 48 bytes grande, y en una tabla de dichos objetos, al menos uno de dos se colocará en dos líneas de caché. –

0

Debido a abordar virtual.

"... la alineación de una página en un límite de tamaño de una página permite el mapa hardware de una dirección virtual a una dirección física mediante la sustitución de los bits superiores de la dirección, en lugar de hacer la aritmética compleja".

Por cierto, encontré la página de Wikipedia bastante bien escrita.

+1

No relacionado .... –

0

Si el tamaño de registro de la CPU es de 32 bits, puede tomar la memoria que está en límites de 32 bits con una única instrucción de ensamblaje. Es más lento tomar 32 bits, y luego obtener el byte que comienza en el bit 8.

BTW: No tiene que haber relleno. Puedes pedir que las estructuras sean empacadas.

+1

El embalaje es específico del compilador, no en el idioma. El embalaje explotará en máquinas RISC, si la CPU/soporte del Kernel para manejar cargas y almacenes desalineados no está allí o no está encendido. Alineación solo para velocidades; es un requisito difícil en algunas máquinas. – Kaz

1

Dependiendo del hardware, la alineación puede ser necesaria o simplemente ayudar a acelerar la ejecución.

Existe una cierta cantidad de procesadores (creo que ARM) en los que un acceso desalineado conduce a una excepción de hardware. Simple y simple.

Aunque los procesadores x86 típicos son más indulgentes, todavía hay una penalización al acceder a tipos fundamentales desalineados, ya que el procesador tiene que trabajar más para incorporar los bits al registro antes de poder operar en él. Los compiladores generalmente ofrecen atributos/pragmas específicos cuando embalaje es deseable, no obstante.

Cuestiones relacionadas