Skip to content

Latest commit

 

History

History
69 lines (39 loc) · 5.24 KB

DataAlignment.adoc

File metadata and controls

69 lines (39 loc) · 5.24 KB

Alineamiento (Data Alignment)

Extraido de IBM developerWorks

Cuando hablamos de "Data alignment" nos referimos a como los datos estarán, alineados en la memoria. Nuestro software puede ser impactado por como estén alineado los datos o hasta llegar a no funcionar.

Memory access granularity

Una de las formas en la cual los programadores piensan en la memoria es como un vector de bytes. Desde C y sus descendientes, char* representa "un bloque de memoria", en Java contamos con byte[] para representar una cadena de bytes.

001

Sin embargo, las computadoras no leen y escriben en la memoria byte x byte, sino que acceden a la memoria en bloque (2, 4, 8, 16, 32 bytes). El tamaño del bloque es conocido como "memory access granularity"

002

La diferencia entre como los programadores piensan en la memoria y como los procesadores modernos trabajan con la memoria, puede generar diversos problemas contemplados en este articulo. Algunos problemas típicos que podemos enfrentar al manejar datos desalineados:

  • Performance issue

  • La aplicación se puede frizar

  • El sistema operativo se puede frizar

  • La aplicación puede fallar y generar resultados incorrectos


Fundamentos (Alignment fundamentals)

Para ilustrar los principios detrás de esto, podemos examinar algunos ejemplos y como distintos tamaños afectan el comportamiento.

Leer 4 bytes desde la dirección 0 y almacenar esto en un registro, luego vamos a leer 4 bytes pero desde la dirección 1.
Veamos que sucede si el "memory access granularity" es de 1 byte

003

Esto se ajusta a nuestra ingenua idea de como la memoria funciona: Podemos ver que necesitamos de 4 acceso a la memoria en cualquiera de los dos casos: Ahora veamos que pasa si el "memory access granularity" es de 2 bytes como el original 68000:

004

Cuando leemos desde la dirección 0, el procesador necesita la mitad de acceso a la memoria, pero cuando leemos desde la dirección 1, los datos están desalineados, entonces se deben procesar acceso innecesarios.
Por ultimo vamos a analizar que pasa con un procesador con 4 bytes de "memory access granularity" como el 68030 o PowerPC® 601:

005

Un procesador con 4 bytes de granularidad puede obtener 4 bytes desde una dirección alineada con un solo acceso. También debemos notar que acceder desde una dirección no alineada duplica el numero de accesos.
Ahora que revisamos los fundamentos básicos detrás del alineamiento de datos podemos explorar otros problemas relacionados con esto.


Lazy processors

Un procesador tiene que aplicar algunos trucos a la hora de acceder a datos no alineados. Volviendo al ejemplo donde leemos 4 bytes desde la dirección 1 con granularidad de 4 bytes, esto es lo que sucede:

006

El procesador lee el primer chunk de 4 bytes, dado que estamos leyendo desde una dirección no alineada debemos remover los bytes que no necesitamos de este chunk. Luego lee el segundo chunk y debe remover los bytes no deseados del final, luego se hace un merge entre estos dos chunks y se almacena en un registro. Esto es mucho trabajo.

Algunos procesadores no están dispuestos a hacer todo ese trabajo por nosotros.

El original 68000 era un procesador con granularidad de 2 bytes y no disponía de la capacidad para leer dirección no alineadas, por lo cual frente a esta situación el procesador arrojaba una excepción. El procesador original de Mac OS no maneja esta operación y ni siquiera arrojaba una excepción, y normalmente obligaba al usuario a reiniciar la maquina. Ouch.

Procesadores mas modernos en la serie 680x0 como el 68020, manejaban esto y realizaban el trabajo necesario por nosotros. Esto explica porque algunos software viejos funcionaban en la 68020 pero no en 68000. Esto también explica por que, antes algunos developers de Mac inicializaban punteros con direcciones impares, en la Mac original si el puntero era accedido sin ser reasignado a una dirección valida, automáticamente se caía en el debugger, y en este estado se podía analizar el stack de llamadas y descubrir el problema.

Todos los procesadores tienen un numero finitos de transistores para realizar el trabajo. Soportar accesos a datos desalineados reduce el numero de transistores para otras tareas, en lugar agregar mas funcionalidad o de hacer trabajar mas rápido al procesador, deben cumplir otras funciones. Un ejemplo de un procesador el cual prefirió sacrificar el soporte para datos alineados y hacer mas rápido su trabajo es MIPS.

PowerPC toma una enfoque hibrido. Cada procesador PowerPC hasta la fecha tiene soporte a nivel hardware para acceso a datos desalineados de 32 bit. De esta forma igual sufrimos una penalización por este acceso pero esta es menor.

Por otro lado, los procesadores modernos PowerPC no poseen soporte a nivel de hardware para acceso a datos desalineados de 64 bits. Cuando se le solicita cargar un numero de punto flotante desde la memoria, este arroja una excepción y el software será el encargado de este acceso a datos, realizar alineamiento por medio de software es mucho mas lento que a nivel de hardware