2009-06-28 36 views
11

Los procesadores Intel de 32 bits como Pentium tienen un bus de datos amplio de 64 bits y, por lo tanto, obtienen 8 bytes por acceso. En base a esto, asumo que las direcciones físicas que estos procesadores emiten en el bus de direcciones siempre son múltiplos de 8.Alineación de memoria en un procesador Intel de 32 bits

En primer lugar, ¿es correcta esta conclusión?

En segundo lugar, si es correcto, entonces uno debe alinear los miembros de la estructura de datos en un límite de 8 bytes. Pero he visto personas que usan una alineación de 4 bytes en cambio en estos procesadores.

¿Cómo pueden justificarse al hacerlo?

+1

No tengo idea de lo que significa esta pregunta, pero estoy intrigado acerca de cómo esto se relaciona con la programación, y cómo esto podría afectarme. ¿Dónde puedo leer una introducción básica a este tipo de cosas de bajo nivel? –

+4

Consulte "Lo que todo programador debe saber sobre la memoria": http://people.redhat.com/drepper/cpumemory.pdf – Crashworks

+1

¿Cómo se puede obtener desde "lecturas solicitadas siempre son múltiplos de 8" hasta "sus datos siempre deben comenzar en un límite de 8 bytes "? No veo la conexión lógica entre estos. Mientras los datos no * crucen * un límite de 8 bytes, estamos bien, ¿verdad? – jalf

Respuesta

14

La regla general (directamente de los manuales de optimización de Intels y AMD) es que cada tipo de datos debe alinearse por su propio tamaño. Un int32 debe alinearse en un límite de 32 bits, un int64 en un límite de 64 bits, y así sucesivamente. Un char encajará bien en cualquier lugar.

Otra regla de oro es, por supuesto, "el compilador ha sido informado sobre los requisitos de alineación". No necesita preocuparse porque el compilador sabe agregar el relleno y las compensaciones correctas para permitir un acceso eficiente a los datos.

La única excepción es cuando se trabaja con instrucciones SIMD, donde debe asegurarse manualmente la alineación en la mayoría de los compiladores.

En segundo lugar, si es correcto, entonces uno debe alinearse miembros de la estructura de datos en un límite de 8 byte. Pero he visto personas usando una alineación de 4 bytes en cambio en estos procesadores.

No veo cómo eso hace la diferencia. La CPU simplemente puede emitir una lectura para el bloque de 64 bits que contiene esos 4 bytes. Eso significa que obtiene 4 bytes adicionales antes de los datos solicitados o después de eso. Pero en ambos casos, solo se necesita una sola lectura. La alineación de 32 bits de datos de 32 bits garantiza que no cruzará un límite de 64 bits.

+0

No si los 4 bytes forman un trozo de 64 bits sobre el siguiente. –

+0

¿cómo sería eso si está alineado en un límite de 4 bytes? – jalf

+5

No puedo creer que me haya olvidado de este simple razonamiento. ¿Por qué perder 4 bytes extra en alineación de 8 bytes cuando logra el mismo rendimiento con 4 bytes? Gracias Jalf. Tu tienes perfecto sentido. –

6

bus física es de 64 bits de ancho ... múltiplo de 8 -> sí

Sin embargo, hay dos factores más a tener en cuenta:

  1. Algunos conjunto de instrucciones x86 son bytes dirigida. Algunos están alineados a 32 bits (es por eso que tienes algo de 4 bytes). Pero ninguna instrucción (núcleo) tiene 64 bits alineados. La CPU puede manejar el acceso a datos desalineados.
  2. Si le importa el rendimiento, debe pensar en la línea de caché, no en la memoria principal. Las líneas de caché son mucho más amplias.
+0

No entiendo. Usted acepta que los procesadores como el Pentium colocan solo múltiplos 8 en el bus de direcciones. Entonces dices que la alineación de 4 bytes está bien. Bien, considere la dirección 0x000044444. Aunque está alineado en 4 bytes, el procesador nunca va a emitir esta dirección en la línea de dirección porque no es un múltiplo de 8. Por lo tanto, recuperar la memoria en esta dirección requerirá dos recuperaciones. ¿Cómo se justifica la alineación de 4 bytes? –

+2

¿Por qué requeriría dos recuperaciones? Simplemente solicitará todos los datos desde 0x000044440 hasta 0x000044447, y como estamos interesados ​​en 0x000044444-0x000044447, ¿cuál es el problema? – jalf

+0

¿Por qué están hablando de alineación de instrucciones? Eso no tiene sentido. Las instrucciones de relleno de algunos límites con NOP no logran nada. –

0

Para el acceso aleatorio y siempre que los datos no estén desalineados (por ejemplo, al cruzar un límite), no creo que importe demasiado; la dirección y el desplazamiento correctos en los datos se pueden encontrar con una construcción AND simple en hardware. Se vuelve lento cuando un acceso de lectura no es suficiente para obtener un valor. Es por eso que los compiladores generalmente ponen pequeños valores (bytes, etc.) juntos porque no tienen que estar en un desplazamiento específico; los cortos deben estar en direcciones pares, 32 bits en direcciones de 4 bytes y 64 bits en direcciones de 8 bytes.

Tenga en cuenta que si tiene acceso de datos invocado y lineal en caché, las cosas serán diferentes.

2

Están justificados para hacerlo porque cambiar a una alineación de 8 bytes constituiría un cambio de ABI, y la mejora del rendimiento marginal no merece la pena.

Como ya ha dicho alguien más, las cachelines son importantes. Todos los accesos en el bus de memoria real están en términos de líneas de caché (64 bytes en x86, IIRC). Vea el documento "Lo que todo programador necesita saber sobre la memoria" que ya se mencionó. Entonces el tráfico de memoria real está alineado en 64 bytes.

1

El bus de 64 bits al que se refiere alimenta las memorias caché. Como CPU, siempre lea y escriba líneas de caché completas. El tamaño de una línea de caché siempre es un múltiplo de 8, y su dirección física está de hecho alineada en desplazamientos de 8 bytes.

Las transferencias de caché a registro no utilizan el bus de datos externo, por lo que el ancho de ese bus es irrelevante.

Cuestiones relacionadas