La contaminación de la caché describe situaciones en las que un programa informático en ejecución carga datos en la caché de la CPU innecesariamente, [ 1 ] lo que provoca que otros datos útiles se desalojen de la caché y se trasladen a niveles inferiores de la jerarquía de memoria , lo que degrada el rendimiento. Por ejemplo, en un procesador multinúcleo , un núcleo puede reemplazar los bloques obtenidos por otros núcleos en la caché compartida, o los bloques precargados pueden reemplazar los bloques obtenidos bajo demanda desde la caché.
Ejemplo
Considere la siguiente ilustración:
T[0] = T[0] + 1; para i en 0.. tamaño de (CACHE) C[i] = C[i] + 1; T[0] = T[0] + C[tamaño(CACHE)-1];
(Aquí se asume que la caché está compuesta por un solo nivel, está desbloqueada, la política de reemplazo es pseudo-LRU , todos los datos son almacenables en caché, la asociatividad de conjuntos de la caché es N (donde N > 1) y, como máximo, hay un registro del procesador disponible para contener valores de programa).
Justo antes de que comience el bucle, T[0] se recupera de la memoria y se carga en la caché, actualizándose su valor. Sin embargo, durante la ejecución del bucle, debido a que la cantidad de elementos de datos a los que hace referencia requiere que la caché se llene por completo, el bloque de caché que contiene T[0] debe ser desalojado. Por lo tanto, la próxima vez que el programa solicite la actualización de T[0], la caché no estará disponible y el controlador de caché deberá solicitar al bus de datos que vuelva a cargar el bloque de caché correspondiente desde la memoria principal .
En este caso, se dice que la caché está "contaminada". Cambiar el patrón de accesos a los datos, colocando la primera actualización de T[0] entre el bucle y la segunda actualización, puede eliminar la ineficiencia:
para i en 0.. tamaño de (CACHE) C[i] = C[i] + 1; T[0] = T[0] + 1; T[0] = T[0] + C[tamaño(CACHE)-1];
Soluciones
Además de la reestructuración del código mencionada anteriormente, la solución al problema de la saturación de la caché consiste en garantizar que solo se almacenen en ella datos de alta frecuencia de uso. Esto se puede lograr mediante instrucciones especiales de control de caché , compatibilidad con el sistema operativo o soporte de hardware.
Ejemplos de instrucciones de hardware especializadas incluyen "lvxl", proporcionada por PowerPC AltiVec . Esta instrucción carga un valor de 128 bits en un registro y marca el bloque de caché correspondiente como "menos usado recientemente", es decir, como el principal candidato para su eliminación cuando sea necesario desalojar un bloque de su conjunto de caché. Para usar adecuadamente esta instrucción en el contexto del ejemplo anterior, los elementos de datos a los que hace referencia el bucle tendrían que cargarse mediante esta instrucción. Al implementarse de esta manera, no se produciría contaminación de la caché, ya que la ejecución de dicho bucle no causaría la eliminación prematura de T[0] de la caché. Esto se evitaría porque, a medida que el bucle avanzara, las direcciones de los elementos en C se asignarían a la misma ruta de caché, dejando intactos los datos más antiguos (pero no marcados como "menos usados recientemente") en las otras rutas. Solo los datos más antiguos (no relevantes para el ejemplo dado) se eliminarían de la caché, de la cual T[0] no es miembro, ya que su actualización ocurre justo antes del inicio del bucle.
De manera similar, utilizando el soporte del sistema operativo (SO), las páginas en la memoria principal que corresponden al array de datos C pueden marcarse como "caché inhibida" o, en otras palabras, no almacenables en caché. De manera similar, a nivel de hardware, se pueden utilizar esquemas de derivación de caché que identifican datos de baja reutilización basados en el patrón de acceso del programa y los derivan de la caché. Además, la caché compartida puede particionarse para evitar interferencias destructivas entre aplicaciones en ejecución. La desventaja de estas soluciones es que los esquemas basados en el SO pueden tener una gran latencia que puede anular la ganancia que se puede lograr al evitar la contaminación de la caché (a menos que la región de memoria no haya sido almacenable en caché desde el principio), mientras que las técnicas basadas en hardware pueden no tener una visión global del flujo de control del programa y el patrón de acceso a la memoria .
Importancia creciente
El control de la contaminación de la caché ha cobrado mayor importancia debido a que las penalizaciones causadas por la denominada " barrera de memoria " siguen aumentando. Los fabricantes de chips continúan ideando nuevas técnicas para superar la creciente latencia relativa entre la memoria y la CPU. Lo logran aumentando el tamaño de la caché y proporcionando a los ingenieros de software herramientas útiles para controlar la forma en que los datos llegan y permanecen en la CPU. El control de la contaminación de la caché es uno de los numerosos dispositivos disponibles para el programador (principalmente de sistemas embebidos). Sin embargo, también se utilizan otros métodos, la mayoría de los cuales son propietarios y altamente específicos del hardware y la aplicación.
Referencias
- Arquitectura de computadoras
- Caché (informática)
- Memoria de computadora