que es la memoria cache
Memoria CACHE
Aunque de origen inglés , la palabra cache ha tomado carta de naturaleza en
Español (no se si los académicos se habrán enterado de ello, por si acaso, la
españolizamos añadiéndole un acento). Utilizada en informática significa
memoria temporal; generalmente de existencia oculta y automática para el
usuario, que proporciona acceso rápido a los datos de uso más frecuente o
previsible. Por ejemplo, el "Caché" de disco es un área de
memoria donde el Sistema transfiere los datos que supuestamente serán accedidos
de inmediato. Si leemos un "cluster" [1] el sistema puede disponer en esta memoria
"cache" los clusters que siguen en la estructura lógica, de forma
que, si seguimos efectuando lecturas, lo más probable es que los próximos datos
estén ya en memoria y puedan ser accedidos de forma inmediata [2].
La utilización de este tipo de memorias no es sino la generalización de un
principio de uso común en la vida diaria; poner más a mano las cosas de uso más
frecuente. Se basa en dos suposiciones que generalmente resultan ciertas:
·
Los ordenadores tienden a utilizar las mismas instrucciones y (en menor
medida), los mismos datos repetidamente.
·
La información necesitada se encuentra almacenada de forma adyacente, o
cuando menos muy cercana, en memoria o disco.
Desde el punto de vista del hardware, existen dos tipos de memoria
cache; interna y externa. La primera,
denominada también cache
primaria, caché
de nivel 1 o simplemente caché L1 (Level one) La
segunda se conoce también como cache secundaria, cache de nivel 2 o cache L2
Desde el punto de vista funcional, existen cachés específicas de algunos
dispositivos, por ejemplo, de disco. También se distingue entre caché de lectura
y de escritura.
2.1 Caché interna
Es una innovación relativamente reciente [3]; en realidad son dos, cada una con una misión
específica: Una para datos y otra para instrucciones. Están
incluidas en el procesador junto con su circuitería de control, lo que
significa tres cosas: comparativamente es muy cara; extremadamente
rápida, y limitada en tamaño (en cada una de las cachés internas, los 386
tenían 8 KB; el 486 DX4 16 KB, y los primeros Pentium 8 KB). Como puede
suponerse, su velocidad de acceso es comparable a la de los registros, es
decir, centenares de veces más rápida que la RAM.
2.2 Caché externa
Es más antigua que la interna, dado que hasta fecha
"relativamente" reciente estas últimas eran impracticables. Es
una memoria de acceso rápido incluida en la placa base, que dispone de su
propio bus y controlador independiente que intercepta las llamadas a memoria
antes que sean enviadas a la RAM ( H2.2 Buses
locales).
La caché externa típica es un banco SRAM ("Static Random Access
Memory") de entre 128 y 256 KB. Esta memoria es considerablemente más
rápida que la DRAM ("Dynamic Random Access Memory") convencional,
aunque también mucho más cara [5] (tenga en cuenta que un aumento de tamaño
sobre los valores anteriores no incrementa proporcionalmente la eficacia de la
memoria caché). Actualmente (2004) la tendencia es incluir esta caché en
el procesador. Los tamaños típicos oscilan entre 256 KB y 1 MB.
Nota: En 1997, con
la introducción del procesador Pentium II, Intel abandonó el denominado zócalo 7 utilizado hasta
entonces en sus procesadores, en favor del denominado Slot-1. La razón
argüida era precisamente la inclusión de la caché L2 en la cápsula
del procesador.
Además de las anteriores, que son de propósito general, existe una caché de
funcionalidad específica que se aloja en memoria RAM estándar. Es la caché de disco (nos hemos
referido a ella en la introducción de este epígrafe), destinada a contener los
datos de disco que probablemente sean necesitados en un futuro próximo y los
que deben ser escritos. Si la información requerida está en chaché, se
ahorra un acceso a disco, lo que es centenares de veces más rápido (recuerde
que los tiempos de acceso a RAM se miden en nanosegundos y los de disco en
milisegundos E1.7.1 Unidades
de medida).
Nota: Existe un
mecanismo parecido al de caché de disco que aquí se describe pero que funciona
en sentido inverso. Es decir, aloja en disco los datos que no pueden ser
almacenados en la memoria RAM. Es el sistema de memoria virtual, al que nos
referiremos al tratar de la memoria.
El funcionamiento de la caché de disco se basa en dos esquemas de
operación. La lectura adelantada ("Read-ahead") y laescritura retrasada ("Write-behind").
La primera consiste en anticipar lo que se necesitará de forma inmediata y
traerlo a la caché. Por su parte, la escritura retrasada consiste en
mantener los datos en caché hasta que se producen momentos de desocupación del
sistema de disco. En este caso la caché actúa como memoria tampón o
"buffer" intermedio, y no se obliga al subsistema a realizar
físicamente ninguna escritura, con lo que las cabezas quedan libres para nuevas
lecturas.
Puesto que los
cachés de disco de escritura retrasada mantienen los datos en memoria volátil
después que "supuestamente" se han escrito en el dispositivo,
una caída accidental del sistema, por fallo de energía o apagado intempestivo,
puede producir pérdidas de los datos alojados en la caché en ese momento (es
esta una de las razones por las que los sistemas Windows y Linux exigen un
proceso especial de apagado, que a veces tarda unos segundos, en los que
observamos una intensa actividad del sistema de disco).
Nota: La mayoría de
los lenguajes disponen de métodos para forzar una escritura "real" de
los datos vaciando la caché de disco; suelen ser sentencias del tipo commit, flush etc. Es una práctica de
seguridad aconsejable, y señal de programación cuidadosa, realizar un vaciado
de "buffers" después de cada transacción importante siempre que las
circunstancias lo permitan
3.1 Caché de disco
en MS DOS y Windows
La cache de los sistemas MS DOS y de los primeros sistemas Windows se
denominaba SmartDrive. Por su parte,
los nuevos Sistemas de 32 bits disponen de un controlador virtual
denominado VCACHE que utiliza un
esquema de funcionamiento de lectura adelantada y escritura atrasada para
proporcionar servicios de cache a las máquinas virtuales ( E0.2).
VCACHE tiene la ventaja cachear ficheros en discos de red, y de permitir
cambiar en tiempo de ejecución la cantidad de memoria destinada a este
menester. Cuando la actividad del disco es elevada pero la ocupación de
memoria es baja, VCACHE incrementa su tamaño para realizar la mayor cantidad de
operación en RAM, evitando de este modo accesos a disco. Por ejemplo, si
la aplicación abre un fichero para lectura/escritura, es posible que VCACHE
vuelque la totalidad del fichero a memoria; posteriormente, quizás cuando se
cierre el fichero, la imagen de memoria sea volcada de nuevo al disco. Si
por el contrario la actividad de disco es pequeña y la ocupación de memoria es
alta, VCACHE disminuye su propio tamaño con objeto de aumentar la RAM
disponible para las aplicaciones.
En la terminología C++ los flujos que son cacheados se denominan
"buffered". A este respecto, los compiladores C/C++ disponen de
su propio sistema de caché para ficheros de disco. Esta caché se
denomina de
ejecución (runtime), para distinguirla de la caché del Sistema. Así mismo,
disponen de recursos en la Librería Estándar para forzar su vaciado en caso
necesario; para esto se recurre a la funciones fflush (para ficheros
abiertos con fopen) y flush (para los flujos
de salida, "ostreams").
Sin embargo, no olvide que el vaciado de la caché del compilador se realiza
sobre la del Sistema, que está por debajo (recuerde que el Software tiene una
estructura de capas E1.7w1), y que el SO
decide por su cuenta cuando es el momento oportuno para realizar físicamente la
escritura de los discos. Esto significa que una seguridad total solo se alcanza
forzando la escritura de la caché del Sistema, y esto naturalmente depende de
la plataforma utilizada.
Nota: Además de las
posibilidades ofrecidas en la Librería Estándar, el compilador MS Visual C++
para Windows ofrece la función _flushall, que fuerza el vaciado de la caché de
ejecución de todos los ficheros abiertos. También dispone de la librería
COMMODE.OBJ, que enlazada con la aplicación, fuerza que las llamadas a fflush y a _flushall escriban
directamente los buffers al disco en vez de a la caché del Sistema.
El siguiente ejemplo muestra algunas
formas de vaciado de los buffers del compilador y de la caché del Sistema
#include <stdio.h>
#include <ofstream.h>
void funcES1() {
FILE*
Fichero1;
// L.5
fflush(Fichero1);
// L.6
_commit(_filenum(Fichero1)); // L.7
}
void funcES2() {
ofstream
Fichero2;
// L.11
Fichero2.flush();
// L.12
_commit(Fichero2.rdbuf()->fd());
// L:13
}
void main()
{
// ========
funcES1();
funcES2();
}
Comentario
L.5 abre el fichero Fichero1 para lectura y escritura.
La llamada a fflush en L.6 fuerza al
programa a vaciar al SO la caché de ejecución asociados al fichero1.
La llamada a _commit en L.7 obliga al
cache de disco del Sistema vaciar sus buffers.
L.11 se instancia un objeto Fichero2 de la plantilla
basic_ofstream<char>, para realizar escritura.
La línea L.12 invoca el método flush para dicho objeto. Esta
invocación fuerza al programa a vaciar al SO los buffers de ejecución asociados
con Fichero2.
La invocación a _commit en L.13 obliga al caché de disco
del Sistema a vaciar los buffers al disco. Esta función requiere un
manejador "handle" referido al fichero; en este caso, el manejador se
obtiene mediante una invocación al método rdbuf.
ofstream.rdbuf()->fd().
Nota: _commit es una función
de MS Visual C++ que obliga al Sistema a vaciar los buffers de un fichero
determinado. No es estándar C++ y solo funciona en Sistemas MS de 16
bits. En los de 32 bits se recurre a la librería Commode.objsegún se ha
indicado
4 Rendimiento de la
caché
El funcionamiento de la caché de lectura se parece al de un adivino; debe
anticipar lo que ocurrirá en el futuro. Si el dispositivo que está
siendo cacheado encuentra los datos en la caché, habrá un éxito
("hit"), en caso contrario, un fracaso ("miss"). Los
sistemas de caché actuales son capaces de proporcionar una tasa de éxitos
superior al 90%.
Como puede figurarse el lector, construir un mecanismo de caché no es una
tarea baladí. Se requieren esquemas de funcionamiento que atiendan de
forma simultanea y balanceada diversos factores:
·
Discriminar que información debe ser almacenada y cual descartada.
·
Decidir la organización interna de este almacenamiento.
·
Manejar las peticiones de lectura. Esto exige disponer de un
mecanismo de intercepción de las peticiones del dispositivo que está siendo
cacheado.
·
Manejar las peticiones de escritura. Interceptar las peticiones de escritura
del dispositivo a cachear.
5 Caché oportunista
Existe un tipo especial que podríamos considerar "de aplicación",
denominada caché
oportunista ("Opportunistic cache"). Está relacionada con los problemas
de bloqueos de ficheros en entornos multiusuario en los que distintas
aplicaciones pueden acceder a los mismos datos.
En estos casos, los Sistemas Operativos disponen de mecanismos para que un
usuario (programa de aplicación) obtenga el bloqueo de todo un fichero o parte
de él. La teoría es que mientras se mantenga el bloqueo, ningún otro
usuario puede modificar el fichero (tal vez si leerlo), y que una vez
finalizadas las modificaciones, el usuario desbloquea el fichero para que otros
puedan utilizarlo. Sin embargo, en determinadas aplicaciones de red, y
con objeto de aumentar el rendimiento, se utiliza un sistema mixto denominado
bloqueo oportunista oplock ("Opportunistic
locking"), en el que el usuario comunica al Sistema que utilizará esta
modalidad [6]. Para ello,
obtiene una copia de la totalidad del fichero, que almacena un una caché local
oportunista. De esta forma, las operaciones son más rápidas que si tiene
que realizarse a través de la red las peticiones de distintos trozos, junto con
las correspondientes solicitudes de bloqueo/desbloqueo. Finalmente,
cuando el usuario ha finalizado las operaciones con el fichero, devuelve al
servidor una copia actualizada.
El problema se presenta cuando, en el intermedio, otro usuario solicita
utilizar el mismo fichero. La incidencia es especialmente frecuente
cuando el fichero a manejar es muy grande. Porque entonces, incluso para
una pequeña modificación, el primer usuario puede demorarse bastante en
devolver la versión modificada al servidor. La solución adoptada para
evitar demoras excesivas, consiste en que, al recibir la petición del segundo
usuario, el Sistema envía al primero una orden de interrumpir el oplock y devolver el
fichero tal como está en ese momento para que el segundo usuario pueda
utilizarlo.
Aunque no exento de problemas, especialmente en redes poco fiables, el
sistema permite aumentos del rendimiento del orden del 30%. No tanto por el
sistema de bloqueo utilizado, como por el hecho de que los datos hayan sido
previamente cacheados por el usuario.
[1] También denominado "Allocation Unit"
o unidad
de asignación en Español. Es el conjunto de sectores de disco que son
tratados por el sistema como una sola unidad de almacenamiento. Su tamaño
(número de sectores de disco) depende del SO y del tamaño de la partición
lógica (MS DOS y Windows utilizan un cluster de 1 sector en los disquetes de
3.5"). Un "Cluster" puede estar ocupado o disponible, pero
no parcialmente ocupado. El Sistema de Archivo de un Sistema
Operativo es precisamente una forma de controlar, asignar, desasignar y acceder
clusters para alojar ficheros en disco ( 8.1.2).
"Cluster" tiene también otra acepción en inglés: Designar
un almacenamiento redundante de datos en sistemas distintos.
Hasta hace pocos años, en que la tecnología de discos ha producido unidades
extremadamente silenciosas, a un oído experimentado le bastaba escuchar la
"música" de los servos para saber si el sistema de "cache"
de disco estaba instalado o no.
Introducida con el Intel 386 SLC que tenía una cache interna para
instrucciones y datos, mientras que en los Pentinum® instrucciones y datos
disponen de cachés separadas.
Bueno, eso es lo que yo creía porque aprendí la palabreja de textos
ingleses, pero D. Julián Cirielli, desde Bs. As. Argentina, me aclara
amablemente que en realidad, la palabra proviene del francés, y significa
escondite/escondida. He preferido mantener intacta mi errónea redacción
anterior e incluir aquí la corrección junto con mi agradecimiento.
El motivo es la propia construcción de la memoria estática, constituida por
conjuntos de seis transistores por cada bit almacenado, lo que las hace mucho
más voluminosas (y caras) que las memorias dinámicas de capacidad comparable;
estas últimas están consituidas por un conjunto de 1 transistor y un
condensador por cada bit. La descarga del condensador es lo que hace que
requieran una actualización (refresco) cada 15 µs (microsegundos)
aproximadamente, lo que añade una dificultad adicional, pues durante la
actualización el sistema queda paralizado (en el bus hay una línea específica,
DACK-0, para indicar que se está produciendo este refresco de la memoria
dinámica
Actualmente (2001), las SRAM tienen tiempos de acceso del orden de 2 a 15
ns (nanosegundos), mientras que en las DRAM es del orden de 60 ns.
Por ejemplo, Samba el popular sistema Linux para compartir recursos sobre
redes TCP/IP, puede utilizar este tipo de caché oportunista con sus clientes.
Etiquetas: memoria cache
0 comentarios:
Publicar un comentario
Suscribirse a Enviar comentarios [Atom]
<< Inicio