¿Por qué hay cachés L1 separados para datos e instrucciones?
23
Acabo de repasar algunas diapositivas y noté que el caché L1 (al menos en las CPU de Intel) distingue entre caché de datos e instrucciones, me gustaría saber por qué esto es ...
Primero y probablemente lo más importante, los datos que se almacenan en la memoria caché de instrucciones generalmente son algo diferentes de lo que se almacena en la memoria caché de datos; junto con las instrucciones en sí, hay anotaciones para cosas como dónde comienza la siguiente instrucción, para ayudar a los decodificadores. Algunos procesadores (por ejemplo, Netburst, algunos SPARCs) usan un "caché de rastreo", que almacena el resultado de decodificar una instrucción en lugar de almacenar la instrucción original en su forma codificada.
En segundo lugar, simplifica un poco los circuitos: el caché de datos tiene que lidiar con lecturas y escrituras, pero el caché de instrucciones solo trata con lecturas. (Esto es parte de por qué el código de modificación automática es tan costoso: en lugar de sobrescribir directamente los datos en la memoria caché de instrucciones, la escritura pasa a través de la memoria caché de datos a la memoria caché L2, y luego la línea en la memoria caché de instrucciones se invalida y se vuelve a -cargado de L2).
En tercer lugar, aumenta el ancho de banda: la mayoría de los procesadores modernos pueden leer datos de la caché de instrucciones y la caché de datos simultáneamente. La mayoría también tiene colas en la "entrada" al caché, por lo que en realidad pueden hacer dos lecturas y una escritura en cualquier ciclo.
Cuarto, puede ahorrar energía. Si bien es necesario mantener la energía de las celdas de memoria para mantener su contenido, algunos procesadores pueden apagar algunos de los circuitos asociados (decodificadores y demás) cuando no se están utilizando. Con cachés separadas, pueden encender estos circuitos por separado para obtener instrucciones y datos, lo que aumenta las posibilidades de que un circuito permanezca sin alimentación durante un ciclo determinado (no estoy seguro de que ningún procesador x86 haga esto; AFAIK, es más un ARM cosa).
También es importante mencionar que el código y los datos pueden exhibir diferentes patrones de acceso; por ejemplo, las instrucciones para sumar todos los elementos en una matriz exhiben localidad temporal (las mismas instrucciones se usan a menudo (si lo hace por un bucle)) y los datos en la matriz exhiben localidad espacial (los siguientes datos se usan a continuación).
gablin
1
@gablin: si bien es cierto, esas diferencias en los patrones a menudo favorecerían un caché unificado. En un ciclo cerrado como usted menciona, la mayor parte del caché de instrucciones está inactivo. Un caché unificado básicamente duplicaría el tamaño del caché de datos durante la duración del ciclo.
Jerry Coffin
En realidad no, porque hay más código después de ese pequeño bucle y también es probable que funcione con la matriz. Eso caracteriza una gran cantidad de código (por ejemplo, manejo de cadenas). De hecho, los primeros cachés en las CPU fueron cachés unificados, se ubicaron entre la interfaz de memoria principal de la CPU y el bus externo, que era un lugar simple para colocarlos, pero ahora usamos un caché particionado porque es más rápido en la práctica .
Donal Fellows
@Donal Fellows: Sí, de verdad. Soy consciente de cómo se realizó el almacenamiento en caché temprano y por qué cambiaron a un caché dividido.
Jerry Coffin
5
Al igual que en el sector inmobiliario, el uso de la memoria caché se basa en tres cosas: ubicación, ubicación, ubicación. El punto principal de tener un caché es que la mayoría de los programas exhiben patrones de ubicación: si acceden al byte 1111111, entonces el siguiente byte al que accederán es probablemente 1111110 u 1111112, y no tanto el byte 9999999. Sin embargo, la mayoría de los programas exhibirán muy diferente patrones de ubicación para sus instrucciones y sus datos. Esto significa que es poco probable que las instrucciones y los datos puedan compartir la memoria caché de manera eficiente. Porque las instrucciones y los datos no están necesariamente cerca uno del otro en la memoria. Un acceso a los datos aumentaría las instrucciones del caché, y las instrucciones de carga elevarían los datos del caché.
Respuestas:
En realidad hay varias razones.
Primero y probablemente lo más importante, los datos que se almacenan en la memoria caché de instrucciones generalmente son algo diferentes de lo que se almacena en la memoria caché de datos; junto con las instrucciones en sí, hay anotaciones para cosas como dónde comienza la siguiente instrucción, para ayudar a los decodificadores. Algunos procesadores (por ejemplo, Netburst, algunos SPARCs) usan un "caché de rastreo", que almacena el resultado de decodificar una instrucción en lugar de almacenar la instrucción original en su forma codificada.
En segundo lugar, simplifica un poco los circuitos: el caché de datos tiene que lidiar con lecturas y escrituras, pero el caché de instrucciones solo trata con lecturas. (Esto es parte de por qué el código de modificación automática es tan costoso: en lugar de sobrescribir directamente los datos en la memoria caché de instrucciones, la escritura pasa a través de la memoria caché de datos a la memoria caché L2, y luego la línea en la memoria caché de instrucciones se invalida y se vuelve a -cargado de L2).
En tercer lugar, aumenta el ancho de banda: la mayoría de los procesadores modernos pueden leer datos de la caché de instrucciones y la caché de datos simultáneamente. La mayoría también tiene colas en la "entrada" al caché, por lo que en realidad pueden hacer dos lecturas y una escritura en cualquier ciclo.
Cuarto, puede ahorrar energía. Si bien es necesario mantener la energía de las celdas de memoria para mantener su contenido, algunos procesadores pueden apagar algunos de los circuitos asociados (decodificadores y demás) cuando no se están utilizando. Con cachés separadas, pueden encender estos circuitos por separado para obtener instrucciones y datos, lo que aumenta las posibilidades de que un circuito permanezca sin alimentación durante un ciclo determinado (no estoy seguro de que ningún procesador x86 haga esto; AFAIK, es más un ARM cosa).
fuente
Al igual que en el sector inmobiliario, el uso de la memoria caché se basa en tres cosas: ubicación, ubicación, ubicación. El punto principal de tener un caché es que la mayoría de los programas exhiben patrones de ubicación: si acceden al byte 1111111, entonces el siguiente byte al que accederán es probablemente 1111110 u 1111112, y no tanto el byte 9999999. Sin embargo, la mayoría de los programas exhibirán muy diferente patrones de ubicación para sus instrucciones y sus datos. Esto significa que es poco probable que las instrucciones y los datos puedan compartir la memoria caché de manera eficiente. Porque las instrucciones y los datos no están necesariamente cerca uno del otro en la memoria. Un acceso a los datos aumentaría las instrucciones del caché, y las instrucciones de carga elevarían los datos del caché.
fuente