Es cierto que no lo entiendo. Digamos que tiene una memoria con una palabra de memoria de longitud de 1 byte. ¿Por qué no puede acceder a una variable de 4 bytes de longitud en un solo acceso de memoria en una dirección no alineada (es decir, no divisible por 4), como es el caso de las direcciones alineadas?
196
Respuestas:
Es una limitación de muchos procesadores subyacentes. Por lo general, se puede solucionar haciendo 4 recuperaciones ineficientes de un solo byte en lugar de una búsqueda eficiente de palabras, pero muchos especificadores de lenguaje decidieron que sería más fácil prohibirlas y forzar que todo esté alineado.
Hay mucha más información en este enlace que descubrió el OP.
fuente
El subsistema de memoria en un procesador moderno está restringido a acceder a la memoria en la granularidad y alineación de su tamaño de palabra; Este es el caso por varias razones.
Velocidad
Los procesadores modernos tienen múltiples niveles de memoria caché por los que deben extraerse los datos; admitir lecturas de un solo byte haría que el rendimiento del subsistema de memoria esté estrechamente vinculado al rendimiento de la unidad de ejecución (también conocido como enlazado a la CPU); Todo esto recuerda cómo DMA superó el modo PIO por muchas de las mismas razones en los discos duros.
La CPU siempre lee en su tamaño de palabra (4 bytes en un procesador de 32 bits), por lo que cuando realiza un acceso de dirección no alineado, en un procesador que lo admite, el procesador leerá varias palabras. La CPU leerá cada palabra de memoria que se encuentre a horcajadas sobre su dirección solicitada. Esto provoca una amplificación de hasta 2 veces el número de transacciones de memoria requeridas para acceder a los datos solicitados.
Debido a esto, puede ser mucho más lento leer dos bytes que cuatro. Por ejemplo, supongamos que tiene una estructura en la memoria que se ve así:
En un procesador de 32 bits, lo más probable es que esté alineado como se muestra aquí:
El procesador puede leer cada uno de estos miembros en una transacción.
Digamos que tenía una versión empaquetada de la estructura, tal vez de la red donde estaba empaquetada para la eficiencia de transmisión; podría verse más o menos así:
Leer el primer byte va a ser lo mismo.
Cuando le pida al procesador que le dé 16 bits de 0x0005, tendrá que leer una palabra de 0x0004 y desplazar 1 byte a la izquierda para colocarlo en un registro de 16 bits; algo de trabajo extra, pero la mayoría puede manejar eso en un ciclo.
Cuando solicite 32 bits de 0x0001 obtendrá una amplificación 2X. El procesador leerá desde 0x0000 en el registro de resultados y cambiará a la izquierda 1 byte, luego leerá nuevamente desde 0x0004 a un registro temporal, cambiará a la derecha 3 bytes y luego
OR
con el registro de resultados.Rango
Para cualquier espacio de direcciones dado, si la arquitectura puede suponer que los 2 LSB son siempre 0 (por ejemplo, máquinas de 32 bits), entonces puede acceder a 4 veces más memoria (los 2 bits guardados pueden representar 4 estados distintos), o la misma cantidad de memoria con 2 bits para algo así como banderas. Quitar los 2 LSB de una dirección le daría una alineación de 4 bytes; También se conoce como un paso de 4 bytes. Cada vez que se incrementa una dirección, está incrementando efectivamente el bit 2, no el bit 0, es decir, los últimos 2 bits siempre seguirán siendo
00
.Esto incluso puede afectar el diseño físico del sistema. Si el bus de direcciones necesita 2 bits menos, puede haber 2 pines menos en la CPU y 2 trazas menos en la placa de circuito.
Atomicidad
La CPU puede operar atómicamente una palabra de memoria alineada, lo que significa que ninguna otra instrucción puede interrumpir esa operación. Esto es crítico para el funcionamiento correcto de muchas estructuras de datos sin bloqueo y otros paradigmas de concurrencia .
Conclusión
El sistema de memoria de un procesador es bastante más complejo e implicado que el descrito aquí; Una discusión sobre cómo un procesador x86 realmente aborda la memoria puede ayudar (muchos procesadores funcionan de manera similar).
Hay muchos más beneficios al adherirse a la alineación de la memoria que puede leer en este artículo de IBM .
El uso principal de una computadora es transformar datos. Las arquitecturas y tecnologías de memoria modernas se han optimizado durante décadas para facilitar la obtención de más datos, entrada, salida y entre más unidades de ejecución más rápidas, de una manera altamente confiable.
Bonus: cachés
Otra alineación por rendimiento a la que aludí anteriormente es la alineación en líneas de caché que son (por ejemplo, en algunas CPU) 64B.
Para obtener más información sobre la cantidad de rendimiento que se puede obtener aprovechando los cachés, eche un vistazo a la Galería de efectos de caché del procesador ; de esta pregunta sobre tamaños de línea de caché
fuente
puedes hacerlo con algunos procesadores ( el nehalem puede hacer esto ), pero anteriormente todo el acceso a la memoria estaba alineado en una línea de 64 bits (o 32 bits), porque el bus tiene 64 bits de ancho, tenías que buscar 64 bits a la vez , y fue significativamente más fácil obtenerlos en 'fragmentos' alineados de 64 bits.
Por lo tanto, si desea obtener un solo byte, obtuvo el fragmento de 64 bits y luego ocultó los bits que no deseaba. Fácil y rápido si su byte estaba en el extremo derecho, pero si estaba en el medio de ese fragmento de 64 bits, tendría que enmascarar los bits no deseados y luego cambiar los datos al lugar correcto. Peor aún, si deseaba una variable de 2 bytes, pero se dividía en 2 fragmentos, entonces eso requería el doble de accesos de memoria requeridos.
Entonces, como todos piensan que la memoria es barata, simplemente hicieron que el compilador alinee los datos en los tamaños de los fragmentos del procesador para que su código se ejecute más rápido y más eficientemente a costa de la memoria desperdiciada.
fuente
Básicamente, la razón es porque el bus de memoria tiene una longitud específica que es mucho, mucho más pequeña que el tamaño de la memoria.
Entonces, la CPU lee en el caché L1 en el chip, que a menudo es de 32 KB en estos días. Pero el bus de memoria que conecta el caché L1 a la CPU tendrá el ancho mucho menor del tamaño de la línea de caché. Esto será del orden de 128 bits .
Entonces:
Los accesos desalineados ocasionalmente se superpondrán con dos líneas de caché, y esto requerirá una lectura de caché completamente nueva para obtener los datos. Incluso podría pasar por alto la DRAM.
Además, una parte de la CPU tendrá que pararse sobre su cabeza para juntar un solo objeto de estas dos líneas de caché diferentes, cada una de las cuales tiene una parte de los datos. En una línea, estará en los bits de orden muy alto, en la otra, los bits de orden muy bajo.
Habrá hardware dedicado totalmente integrado en la tubería que maneja el movimiento de objetos alineados en los bits necesarios del bus de datos de la CPU, pero tal hardware puede faltar para los objetos desalineados, porque probablemente tenga más sentido usar esos transistores para acelerar correctamente optimizado programas
En cualquier caso, la segunda lectura de memoria que a veces es necesaria ralentizaría la tubería, sin importar cuánto hardware dedicado (hipotética e insensatamente) se dedicara a reparar las operaciones de memoria desalineadas.
fuente
@joshperry ha dado una excelente respuesta a esta pregunta. Además de su respuesta, tengo algunos números que muestran gráficamente los efectos que se describieron, especialmente la amplificación 2X. Aquí hay un enlace a una hoja de cálculo de Google que muestra cómo se ve el efecto de las diferentes alineaciones de palabras. Además, aquí hay un enlace a una esencia de Github con el código para la prueba. El código de prueba está adaptado del artículo escrito por Jonathan Rentzsch al que @joshperry hizo referencia. Las pruebas se realizaron en un Macbook Pro con un procesador Intel Core i7 de cuatro núcleos a 2,8 GHz de 64 bits y 16 GB de RAM.
fuente
x
yy
coordinan?Si un sistema con memoria direccionable por byte tiene un bus de memoria de 32 bits de ancho, eso significa que efectivamente hay cuatro sistemas de memoria de byte ancho que están todos conectados para leer o escribir la misma dirección. Una lectura alineada de 32 bits requerirá información almacenada en la misma dirección en los cuatro sistemas de memoria, por lo que todos los sistemas pueden suministrar datos simultáneamente. Una lectura no alineada de 32 bits requeriría que algunos sistemas de memoria devuelvan datos de una dirección, y que algunos devuelvan datos de la siguiente dirección más alta. Aunque hay algunos sistemas de memoria que están optimizados para poder cumplir con tales solicitudes (además de su dirección, efectivamente tienen una señal de "más uno" que les hace usar una dirección más alta que la especificada), tal característica agrega un costo considerable y complejidad para un sistema de memoria;
fuente
Si tiene un bus de datos de 32 bits, las líneas de dirección del bus de direcciones conectadas a la memoria comenzarán desde A 2 , por lo que solo se puede acceder a las direcciones alineadas de 32 bits en un solo ciclo de bus.
Entonces, si una palabra abarca un límite de alineación de dirección, es decir, A 0 para datos de 16/32 bits o A 1 para datos de 32 bits no son cero, se requieren dos ciclos de bus para obtener los datos.
Algunas arquitecturas / conjuntos de instrucciones no admiten acceso no alineado y generarán una excepción en tales intentos, por lo que el código de acceso no alineado generado por el compilador requiere no solo ciclos de bus adicionales, sino instrucciones adicionales, lo que lo hace aún menos eficiente.
fuente
En PowerPC puede cargar un número entero desde una dirección impar sin problemas.
Sparc e I86 y (creo) Itatnium aumentan las excepciones de hardware cuando intentas esto.
Una carga de 32 bits frente a cuatro cargas de 8 bits no hará una gran diferencia en la mayoría de los procesadores modernos. Si los datos ya están en caché o no tendrá un efecto mucho mayor.
fuente