Pregunta

La verdad es que no lo entiendo. Digamos que tiene una memoria con una palabra de memoria de longitud de 1 byte. ¿Por qué no se puede acceder a una variable larga de 4 bytes en un solo acceso a la memoria en una dirección no alineados (es decir. No es divisible por 4), ya que es el caso con las direcciones alineadas?

¿Fue útil?

Solución

Es una limitación de muchos procesadores subyacentes. Por lo general, se puede evitar haciendo un solo byte 4 ineficiente obtiene en vez de buscar a una palabra eficaz, pero muchas especificadores de idioma decidió que sería más fácil simplemente fuera de la ley y obligarlos todo para estar alineados.

Hay mucha más información en este enlace descubrió que el PO.

Otros consejos

El subsistema de memoria en un procesador moderno se limita a acceder a la memoria en la granularidad y la alineación de su tamaño de palabra; este es el caso para un número de razones.

Velocidad

Los procesadores modernos tienen múltiples niveles de la memoria caché que los datos deben ser tirados a través; el apoyo de un solo byte lee haría que el rendimiento del subsistema de memoria firmemente unido al rendimiento de la unidad de ejecución (también conocido como vinculados a la CPU); todo esto es una reminiscencia de cómo PIO fue superada por DMA por muchas de las mismas razones que 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 lo hace un no alineado acceso de dirección - en un procesador que lo soporta - el procesador va a leer varias palabras. La CPU leerá cada palabra de memoria que su dirección solicitada extiende a ambos lados. Esto provoca una amplificación de hasta 2 veces el número de transacciones de memoria necesarios para acceder a los datos solicitados.

Debido a esto, puede ser muy fácilmente lento para leer dos bytes de cuatro. Por ejemplo, supongamos que tiene una estructura en la memoria que tiene este aspecto:

struct mystruct {
    char c;  // one byte
    int i;   // four bytes
    short s; // two bytes
}

En un procesador de 32 bits sería más probable estar alineados como se muestra aquí:

Struct Layout

El procesador puede leer cada uno de estos miembros en una transacción.

Supongamos que tenía una versión compacta de la estructura, tal vez de la red en la que estaba lleno de eficiencia de la transmisión; podría ser algo como esto:

Packed Struct

Al leer el primer byte va a ser el mismo.

Cuando se le pregunta el procesador para darle 16 bits de 0x0005 tendrá que leer una palabra de desde 0x0004 y el desplazamiento a la izquierda de 1 byte para colocarlo en un registro de 16 bits; un trabajo extra, pero la mayoría puede manejar en un ciclo.

Cuando pide 32 bits desde 0x0001 obtendrá una amplificación 2X. El procesador leerá de 0x0000 en el registro de resultado y la desviación a la izquierda de 1 byte, a continuación, leer de nuevo desde 0x0004 en un registro temporal, desplazamiento a la derecha 3 bytes, entonces OR con el registro de resultados.

Gama

Para cualquier espacio de direcciones determinado, si la arquitectura puede asumir que los 2 bits menos significativos son siempre 0 (por ejemplo, máquinas de 32 bits), entonces se pueden acceder a 4 veces más memoria (los 2 bits guardadas pueden representar 4 estados distintos), o la misma cantidad de memoria con 2 bits para algo así como banderas. Tomando los 2 bits menos significativos fuera de una dirección que le dará una alineación de 4 bytes; También se refiere como un paso de 4 bytes. Cada vez que una dirección se incrementa se está incrementando de manera efectiva el bit 2, no bit 0, es decir, los últimos 2 bits siempre seguirá siendo 00.

Esto incluso puede afectar el diseño físico del sistema. Si el bus de direcciones necesita menos bits 2, no puede haber 2 menos pines de la CPU, y 2 menos huellas en la placa de circuito.

atomicidad

La CPU puede operar en una palabra alineado de memoria atómicamente, lo que significa que ninguna otra instrucción puede interrumpir esa operación. Esto es fundamental para el correcto funcionamiento de muchas bloquear libres de estructuras de datos y otros paradigmas concurrencia .

Conclusión

El sistema de memoria de un procesador es un poco más complejo y complicado que se describe aquí; una discusión sobre cómo un procesador x86 en realidad se dirige a la memoria puede ayudar a (muchos procesadores funcionan de manera similar ).

Hay mningún más beneficios a la adhesión a la alineación de memoria que se pueden leer en este artículo IBM .

El uso principal de un ordenador es transformar los datos. arquitecturas de memoria y tecnologías modernas han optimizado durante décadas para facilitar la obtención de más datos, dentro, fuera, y entre más y más rápidas unidades de ejecución en una manera altamente fiable.

Bono: Cachés

Otra alineación por rendimiento que he aludido es previamente de alineación en líneas de caché que son (por ejemplo, en alguna CPU) 64B.

Para obtener más información sobre la cantidad de rendimiento puede ser adquirida mediante el aprovechamiento de las cachés, echar un vistazo a Galería de procesador de efectos caché ; de esta cuestión en caché línea tamaños

  

La comprensión de líneas de caché puede ser importante para ciertos tipos de optimizaciones del programa. Por ejemplo, la alineación de los datos puede determinar si una operación toca una o dos líneas de caché. Como vimos en el ejemplo anterior, esto fácilmente puede significar que en el caso desalineada, la operación será dos veces más lento.

puede con algunos procesadores ( la nehalem puede hacer este ), pero previamente todos los accesos a memoria se alinean en un 64 bits (o línea de 32 bits), porque el autobús es de 64 bits de ancho, había que ir a buscar 64 bits a la vez, y era mucho más fácil se ha podido recuperar estos en 'trozos' alineadas de 64 bits.

Por lo tanto, si desea obtener un solo byte, el que obtuvo el trozo de 64 bits y luego enmascarada los bits que no quería. Fácil y rápida si su byte estaba en el extremo derecho, pero si estaba en el medio de ese trozo de 64 bits, que tendría que enmascarar los bits no deseados y luego cambiar los datos a través de al lugar correcto. Peor aún, si desea una variable de 2 bytes, pero que se dividió, distribuidas en 2 trozos, a continuación, accede a la que se requiere el doble de la memoria necesaria.

Así que, como todo el mundo piensa memoria es barato, que acaba de hacer el compilador alinear los datos sobre el procesador trozo de tamaños, por lo que su código se ejecuta más rápido y más eficiente en el coste de la memoria desperdiciada.

En el fondo, la razón es porque el bus de memoria tiene cierta extensión específica que es mucho, mucho más pequeño que el tamaño de la memoria.

Por lo tanto, la CPU lee fuera de la caché L1 en el chip, que a menudo se 32KB estos días. Pero el bus de memoria que conecta la caché L1 a la CPU tendrá el ancho muy pequeño del tamaño de línea de caché. Esta será del orden de 128 los bits .

Así que:

262,144 bits - size of memory
    128 bits - size of bus

Los accesos estén desalineadas, de vez en cuando se superponen dos líneas de caché, y esto requerirá leer con el fin de obtener los datos de una nueva caché. Incluso podría perder todo el camino a la DRAM.

Además, una parte de la CPU tendrá que estar de pie en su cabeza para juntar un único objeto de estas dos líneas de caché diferentes que tienen cada uno un trozo de los datos. En una línea, será en los bits de orden muy elevado, en la otra, los bits de muy bajo orden.

Habrá hardware dedicado plenamente integrado en la tubería que se encarga de mover objetos alineados a los bits necesarios del bus de datos de la CPU, pero ese tipo de hardware o le falta para objetos desalineados, porque es probable que tenga más sentido usar esos transistores por exceso de velocidad optimizado correctamente los programas.

En cualquier caso, la segunda lectura de la memoria es a veces necesario ralentizaría la tubería no importa cómo era mucho hardware de propósito especial (hipotéticamente y tontamente) dedicado a remendar las operaciones de memoria desalineadas.

@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 describen, especialmente la amplificación 2X. Aquí hay un enlace a un Google hoja de cálculo que muestra lo que el efecto de diferentes alineaciones de palabras parecen. Además aquí hay un enlace a un Github GIST con el código para la prueba. El código de prueba es una adaptación de el artículo escrito por Jonathan Rentzsch cuales @joshperry se hace referencia. Las pruebas se realizaron en un Macbook Pro con una de cuatro núcleos 2.8 GHz Intel Core i7 procesador de 64 bits y 16 GB de RAM.

introducir descripción de la imagen aquí

Si un sistema de memoria direccionable por bytes tiene un bus de memoria de 32 bits de ancho, lo que significa que hay cuatro sistemas de memoria de manera efectiva a nivel de bytes que están todos conectados a leer o escribir en la misma dirección. Una lectura de 32 bits alineados requerirá información almacenada en la misma dirección en los cuatro sistemas de memoria, por lo que todos los sistemas puede suministrar datos al mismo tiempo. Una lectura no alineado de 32 bits requeriría algunos sistemas de memoria para devolver datos desde una dirección, y otros para devolver datos de la siguiente dirección más alta. Aunque hay algunos sistemas de memoria que están optimizados para poder cumplir con esas solicitudes (además de su dirección, que efectivamente tienen una señal "más uno", que hace que se use una dirección de un superior a la especificada) tal característica añade un costo considerable y la complejidad de un sistema de memoria; la mayoría de los sistemas de memoria de los productos básicos simplemente no pueden volver porciones de diferentes palabras de 32 bits al mismo tiempo.

Si usted tiene un bus de datos de 32 bits, las líneas del bus de direcciones de direcciones conectadas a la memoria comenzarán desde A 2 , por lo que sólo las direcciones de 32 bits alineados se puede acceder en un solo ciclo de bus.

Así que si una palabra se extiende por una dirección de alineación límite - es decir, A 0 para los datos de 16/32 bits o A 1 para datos de 32 bits no son cero, dos ciclos de bus se requieren para obtener los datos.

Algunas arquitecturas / conjuntos de instrucciones no son compatibles con el acceso no alineado y generarán una excepción en tales intentos, por lo que el compilador genera código de acceso no alineado requiere no sólo los ciclos de bus adicionales, pero las instrucciones adicionales, lo que hace aún menos eficiente.

En PowerPC que es posible cargar un número entero de una dirección impar sin problemas.

Sparc y I86 y (creo) Itatnium lanzar excepciones de hardware cuando intenta esto.

Una carga de 32 bits vs cuatro cargas de 8 bits isnt va a hacer una gran diferencia en la mayoría de los procesadores modernos. Si los datos que ya están en la caché o no es, tendrá un efecto mucho mayor.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top