Tamaño de linea de la cache

Tamaño de linea de la cache

de Rafael Agustin Castelli Ottati -
Número de respuestas: 1

Buenas, me quedaron algunas dudas respecto a la transferencia de datos entre memoria y la cache:

Por lo que entendi del teorico, debido al principio de localidad espacial, cuando se copia una porcion de la memoria en la cache, no se copia solo el byte o palabra a la cual se accede, sino que se trae todo un bloque de entre 2 a 8 bytes/palabras "que empiezan" en la direccion a la cual se quiere acceder, porque es probable que dado un acceso a memoria, se accedan tambien las direcciones inmediatamente posteriores.
Primeramente, no me termina de quedar claro porque los bloques/lineas de la cache pueden ser grupos de X bytes o de X palabras. Supongo que depende de si la CPU direcciona a memoria o a palabra se usara una o la otra forma. Es correcto?
Por otro lado, supongamos que un bloque esta formado por 2 bytes. Supuestamente, tener bloques de 4 bytes aumenta la eficiencia del sistema de cache porque me estoy trayendo mas direcciones de memoria que son probables que se accedan, pero no se demora el doble de tiempo en traer 4 bytes que 2? Porque si yo tengo una memoria que tiene un bus de datos de ancho 2 bytes, tener una cache con un tamaño de linea de 4 bytes me implicaria tener que hacer 2 transacciones para traerme los 4 bytes. No seria entonces mejor traerme 2 bytes, que es lo maximo que puedo realizar en una transferencia con la memoria, y traerme los otros 2 si los necesito, en vez de preventivamente, pero con mayor coste de tiempo, traerme los 4 bytes juntos?
Por ultimo, creo que se habia dicho que por lo general el tamaño de las lineas de cache son de 2-4-8 bytes, porque tamaños mayores no dan un aumento significativo del rendimiento, pero el aumento que tendra en rendimiento usar lineas de mayor tamaño no dependeria tambien de la arquitectura con la que se trabaja? Por ejemplo si tengo una arquitectura de 16 bits, 2 bytes son una palabra, entonces teniendo 4-8 bytes tengo 2-3 palabras. Sin embargo si uso ese mismo tamaño para una arquitectura de 64 bits, una linea no termina de representar una palabra. Ademas, si tengo arquitecturas de mayor cantidad de bits, no es mas comun que se usen tipos de datos de "mayor largo" (por ejemplo usar int en vez de short) y por tanto me cambiene agrandar mas la linea de cache respecto a una arquitectura de menor cantidad de bits? Es mas caro hacer lineas mas grandes?

Desde ya muchas gracias,
saludos,
Rafael

En respuesta a Rafael Agustin Castelli Ottati

Re: Tamaño de linea de la cache

de Federico Rivero -

Hola Rafael! Contesto entrelíneas:

Por lo que entendi del teorico, debido al principio de localidad espacial, cuando se copia una porcion de la memoria en la cache, no se copia solo el byte o palabra a la cual se accede, sino que se trae todo un bloque de entre 2 a 8 bytes/palabras "que empiezan" en la direccion a la cual se quiere acceder, porque es probable que dado un acceso a memoria, se accedan tambien las direcciones inmediatamente posteriores.

Comentario nomás, los bloques son potencias de 2, pero sin máximo. Es decir, pueden ser mayores a 8.

Primeramente, no me termina de quedar claro porque los bloques/lineas de la cache pueden ser grupos de X bytes o de X palabras. Supongo que depende de si la CPU direcciona a memoria o a palabra se usara una o la otra forma. Es correcto?

Sí, la aclaración que hacemos en teórico al escribir 'palabras o bytes', es para incluir a las CPU que direccionan de a byte y a aquellas que direccionan de a palabra.

Por otro lado, supongamos que un bloque esta formado por 2 bytes. Supuestamente, tener bloques de 4 bytes aumenta la eficiencia del sistema de cache porque me estoy trayendo mas direcciones de memoria que son probables que se accedan, pero no se demora el doble de tiempo en traer 4 bytes que 2? Porque si yo tengo una memoria que tiene un bus de datos de ancho 2 bytes, tener una cache con un tamaño de linea de 4 bytes me implicaria tener que hacer 2 transacciones para traerme los 4 bytes. No seria entonces mejor traerme 2 bytes, que es lo maximo que puedo realizar en una transferencia con la memoria, y traerme los otros 2 si los necesito, en vez de preventivamente, pero con mayor coste de tiempo, traerme los 4 bytes juntos?

Este punto es interesante. Lo principal es que no es cierto que traer 4 bytes demore el doble que traer 2 bytes (el último ejercicio del práctico que puede dar esa idea, pero no es correcto, es una simplificación). Las memorias RAM tienen tiempos de acceso bastante más lentos que las memorias cache, pero típicamente son buenas realizando accesos 'en ráfaga', es decir, que el tiempo de acceso de un byte puede ser largo, pero la RAM retorna bytes a partir de esa dirección más rápidamente. Entonces, es más conveniente traer un poco más de memoria, aumentando el tiempo de acceso 'ligeramente', y no tener un miss la próxima vez, por el cual habría que pagar en el miss penalty entero, nuevamente.

Habiendo dicho esto, igual no es conveniente que los bloques sean 'tan grandes como sea posible', porque si el programa no tiene suficiente localidad espacial, se estaría trayendo información que no se va a utilizar, y por tanto enlenteciendo cada acceso a memoria sin una razón justificada.

Por ultimo, creo que se habia dicho que por lo general el tamaño de las lineas de cache son de 2-4-8 bytes, porque tamaños mayores no dan un aumento significativo del rendimiento, pero el aumento que tendra en rendimiento usar lineas de mayor tamaño no dependeria tambien de la arquitectura con la que se trabaja? Por ejemplo si tengo una arquitectura de 16 bits, 2 bytes son una palabra, entonces teniendo 4-8 bytes tengo 2-3 palabras. Sin embargo si uso ese mismo tamaño para una arquitectura de 64 bits, una linea no termina de representar una palabra. Ademas, si tengo arquitecturas de mayor cantidad de bits, no es mas comun que se usen tipos de datos de "mayor largo" (por ejemplo usar int en vez de short) y por tanto me cambiene agrandar mas la linea de cache respecto a una arquitectura de menor cantidad de bits? Es mas caro hacer lineas mas grandes?

Es correcto lo que decís, el tamaño de línea/bloque depende de muchos factores: el tamaño de la arquitectura, el tipo de procesador (está optimizado para alguna una tarea? es de propósito general?), el nivel de cache, si la cache es de datos/instrucciones, etc. No es más caro hacer líneas más grandes, pero lo que hay que saber es que si aumentás el tamaño de línea y no aumentás la capacidad de la cache, disminuís la cantidad de líneas, por lo tanto ahí hay que fijarse en cómo son los accesos típicos de los programas, para medir qué conviene hacer. 

Por un ejemplo real, El libro de Hennessy & Patterson 5ta edición, incluye un par de ejemplos de jeraraquías de memoria reales (página 113), la del ARM Cortex A8 y la del Intel Core I7, ambas usan 64 bytes de bloque, tanto para instrucciones como para datos.

Saludos!

         Federico