La caché guarda copias de datos que probablemente volverán a necesitarse
La memoria caché es un almacenamiento pequeño y rápido que conserva temporalmente datos o instrucciones para evitar buscarlos cada vez en una memoria más lenta. En un procesador, se sitúa entre los núcleos y la RAM. Cuando el dato solicitado ya está presente ocurre un acierto; si falta, se produce un fallo y debe recuperarse desde otro nivel, con una penalización de tiempo y energía. La mejora surge cuando el coste medio de acertar compensa los fallos y el trabajo de mantener copias coherentes; por eso su eficacia depende del patrón de acceso.
La caché no sustituye a la memoria RAM. Guarda copias seleccionadas y puede desecharlas sin perder el original. Tampoco es lo mismo que la caché de un navegador o una red de distribución, aunque comparten la idea de acercar contenido frecuente. Cada capa aplica políticas distintas porque el coste de mover una línea de CPU no se parece al de descargar una imagen por internet.
La localidad temporal y espacial hace que una caché pueda acertar
La localidad temporal significa que un dato usado hace poco tiende a reutilizarse: una variable dentro de un bucle es el ejemplo típico. La localidad espacial indica que, al acceder a una dirección, probablemente se usarán posiciones cercanas, como elementos consecutivos de un vector. Por eso la caché mueve bloques o líneas completas, no cada byte aislado.
Un programa que recorre una matriz por el orden en que está almacenada aprovecha líneas consecutivas; recorrerla con grandes saltos puede cargar bloques y utilizar solo una fracción. La diferencia no cambia el algoritmo matemático, pero sí su rendimiento. Compiladores y procesadores intentan anticipar accesos mediante prefetch, aunque una predicción errónea consume ancho de banda y puede expulsar información útil.
L1, L2 y L3 intercambian capacidad por velocidad
L1 suele ser la caché más pequeña y rápida, a menudo separada en instrucciones y datos para cada núcleo. L2 ofrece más capacidad con algo más de latencia. L3 suele ser mayor y compartida entre varios núcleos, aunque la arquitectura concreta varía. Buscar en niveles sucesivos forma una jerarquía: un fallo de L1 todavía puede resolverse en L2 sin llegar a RAM.
El tiempo medio depende de la latencia de cada nivel y de su tasa de aciertos. Una caché enorme no siempre mejora: aumenta área, consumo y tiempo de búsqueda. Los diseñadores equilibran tamaño de línea, asociatividad y número de niveles. La memoria virtual añade TLB, una caché especializada para traducir direcciones; fallar allí es distinto de no encontrar los datos en la caché convencional.
Mapeo, reemplazo y escritura deciden qué ocurre cuando el espacio se llena
En una caché de mapeo directo, cada bloque de memoria solo puede ocupar una posición; es simple, pero dos direcciones que compiten expulsan repetidamente sus líneas. La asociatividad permite varias posiciones posibles dentro de un conjunto y reduce esos conflictos a cambio de más comparaciones. Cuando todas están ocupadas, una política aproxima qué línea será menos útil, por ejemplo mediante variantes de LRU.
En write-through, cada escritura se propaga inmediatamente al nivel inferior; simplifica coherencia pero genera tráfico. En write-back, la línea modificada se escribe al expulsarla y necesita un bit sucio. También debe decidirse qué hacer ante un fallo de escritura. Estas opciones muestran que caché no significa solo guardar: es un protocolo para mantener copias y controlar cuándo se actualizan.
Varios núcleos necesitan coherencia y las métricas deben interpretarse
Si dos núcleos conservan copias de una línea y uno la modifica, el otro no puede seguir leyendo una versión antigua. Protocolos de coherencia intercambian estados e invalidaciones. El falso compartido aparece cuando hilos modifican variables independientes situadas en la misma línea: no comparten el dato, pero la línea rebota entre núcleos y reduce rendimiento.
Una tasa de aciertos alta no garantiza un programa rápido si los pocos fallos bloquean una ruta crítica. Contadores de hardware registran accesos, refills y fallos, pero deben relacionarse con instrucciones y tiempo. Optimizar exige medir con datos reales: reorganizar estructuras, bloquear matrices o reducir el conjunto de trabajo puede ayudar; vaciar la caché o añadir memoria RAM no corrige automáticamente un patrón de acceso deficiente.
Los fallos se clasifican para entender su origen. El primer acceso a un bloque produce un fallo obligatorio; una caché demasiado pequeña genera fallos de capacidad; un mapeo restrictivo provoca conflictos aunque quedaría espacio en otras posiciones. Aumentar capacidad ayuda al segundo tipo, pero quizá no al tercero. Esta separación guía cambios de hardware y de software y evita atribuir todo fallo a falta de memoria.
Una línea grande aprovecha localidad espacial y reduce metadatos, pero trae bytes que quizá no se usen y encarece cada fallo. La asociatividad reduce conflictos, aunque eleva consumo y latencia de búsqueda. Los procesadores modernos permiten varios fallos pendientes y ejecución fuera de orden para ocultar esperas; por eso sumar latencias nominales no predice directamente el tiempo de un programa.
Las vulnerabilidades de canal lateral mostraron que la caché también filtra información. Medir tiempos de acceso puede revelar qué líneas utilizó otro contexto, incluso sin leer sus datos directamente. Ataques como Spectre explotan especulación y huellas microarquitectónicas. Mitigarlos requiere software, sistema operativo y procesador, con posibles costes de rendimiento. La caché es transparente para el resultado funcional, pero no para el tiempo, la energía ni la seguridad.



