• No se han encontrado resultados

Memoria virtual

La técnica de gestión de memoria conocida como memoria virtual consiste en tener cargadas en memoria principal solo aquellas partes (páginas o segmentos) del espacio de direcciones lógicas, ahora también llamadas direcciones virtuales, de un proceso que se van necesitando durante su ejecución.

La memoria virtual permite ampliar el grado de multiprogramación, dado que en memoria principal caben más procesos si sólo se cargan algunas partes de cada proceso.

La implementación de la memoria virtual requiere que el hardware soporte el reinicio de las

instrucciones de su repertorio. Además, suele utilizarse un componente denominado unidad de gestión de memoria (Memory Management Unit, MMU), encargada de realizar la traducción de la

dirección virtual a la dirección física.

La memoria virtual puede implementarse usando paginación por demanda (UNIX, Linux, Windows), segmentación por demanda (OS/2) o segmentación con paginación por demanda (Multics)

Paginación por demanda

La técnica de paginación por demanda divide el espacio de memoria principal en bloques de igual tamaño, marcos de página, y el espacio de direcciones del proceso en bloques de igual tamaño, páginas.

Para que un proceso se pueda ejecutar no es necesario que todas sus páginas se encuentren cargadas en memoria principal. Cuando se referencia una página no cargada se produce un fallo de página. Otras tareas a realizar por el Sistema Operativo son:

Reemplazamiento de páginas, en caso de que se produzca un fallo de página y no haya

ningún marco libre, es necesario decidir qué marco hay que intercambiar a memoria secundaria.

Asignación de marcos de memoria principal. El sistema debe decidir cuántos marcos asignar

inicialmente a cada proceso.

Control de carga, decidir el grado de multiprogramación del sistema.

Copia en memoria secundaria de páginas modificadas, en qué momento y de qué forma.

Se mantienen las siguentes estructuras de datos: tabla de marcos de página, listas de marcos libres y tablas de páginas.

Cuando un proceso entra en estado preparado para ejecución se crea una tabla de páginas en memoria principal en la que cada entrada contiene, al menos, los siguientes campos:

• Número de marco de página.

• Validez o presencia, que indica si la página es válida o no.

• Protección, de uno a tres bits que indican los permisos de R, W y X.

• Referenciada, un bit activo cuando la página es referenciada por una dirección virtual.

• Modificada, un bit que indica si la página ha sido modificada y debe ser actualizada en memoria secundaria.

Reinicio de instrucciones

Un fallo de página puede producirse tanto en la fase de búsqueda, al intentar traducir la siguiente instrucción a ejecutar, como de ejecución, en la búsqueda de operandos.

La arquitectura del computador debe poder reiniciar la instrucción desde su inicio, fase de búsqueda. Para ello, se suele disponer de un registro donde se almacena el valor del registro contador de programa CP antes de iniciar la fase de búsqueda.

En caso de que el procesador soporte direccionamiento indexado también deberá guardarse el valor del registro índice por si fuera necesario restaurarlo tras un fallo de página.

Localización de las páginas en memoria secundaria

Cuando la referencia a una página produce un fallo de página el sistema operativo debe leer esa página desde la memoria secundaria y copiarla a la memoria principal. De igual modo, si no hay marcos libres en la memoria principal el sistema operativo debe seleccionar una página para ser reemplazada y, si esta ha sido modificada o no existe en el área de intercambio, debe ser copiada allí.

El sistema operativo puede buscar en dos posibles localizaciones de memoria secundaria:

Bloque de disco de un archivo ejecutable. Parte de las páginas en que se divide el espacio de

direcciones, código y datos, son creadas por el sistema operativo a partir del archivo ejecutable del que es instancia el proceso.

Bloque de disco del área de intercambio, utilizada para el almacenamiento de las páginas de

un proceso cuando se intercambia fuera y para el almacenamiento de las páginas que han sido seleccionadas para ser reemplazadas tras un fallo de página.

Cada bloque del área de intercambio se identifica por un número de bloque o dirección de disco. El sistema mantiene ciertas estructuras de datos para localizar los bloques donde se encuentran almacenadas las páginas.

Algunos sistemas copian por adelantado al área de intercambio todas las páginas de un proceso cuando es creado con el fin de acelerar el tratamiento de los fallos de página. Pero si el espacio de direcciones del proceso crece es necesario aumentar el tamaño en disco por lo que hay que mover todo el espacio del proceso. Para evitar esto, se copia el proceso por partes, datos, código, etc. de manera que si sólo es preciso crecer la parte de datos el trabajo es menor.

Otros sistemas no copian el espacio de direcciones completo a memoria de intercambio, sólo las páginas que son necesarias. En ese caso, se utiliza una estructura de datos denominada tabla de

disco donde se relaciona cada página con el bloque de disco donde se encuentra alojada.

Bloqueo de marcos de página

Se dice que un marco de memoria está bloqueado o pinchado (pinning) si su contenido no puede ser reemplazado. Este bloqueo resulta útil si el marco contiene información que conviene que no sea borrada, por ejemplo los marcos reservados para alojar el espacio del núcleo.

Tratamiento de un fallo de página

Cuando durante el ciclo de ejecución de una instrucción se hace referencia a una determinada posición de memoria, la dirección de memoria virtual es pasada a la MMU para traducirla a una dirección física. Ésta comprueba que la dirección está dentro del rango de direcciones permitido. Si lo está accede a la tabla de páginas y comprueba el bit de validez o presencia. Si está activado, la página se encuentra en memoria principal, con lo que la MMU toma el valor del campo de marco de página para construir la dirección física junto al desplazamiento de la dirección virtual.

Si el bit de validez está desactivado se produce un fallo de página y se guarda en la pila el contenido del contador del programa y de los registros especiales y pasa el control al sistema operativo.

El sistema operativo guarda el contexto del proceso cuya ejecución produjo la excepción y comprueba que, en efecto, se debe a un fallo de página. A continuación intenta averiguar la dirección que produjo el fallo, bien consultado registros internos del procesador o simulando su ejecución.

Determinada la dirección se comprueba que ésta sea legal, si no lo es se aborta el proceso. Si la dirección sí es legal, se consulta la lista de marcos libres y si no ha y ninguno se invoca a un algoritmo de reemplado para seleccionar un marco donde cargar la página que produjo el fallo. Si la página contenida en el marco elegido ha sido modificada, se planifica para ser copiada a disco duro y mientras tanto se bloquea el proceso y el marco para evitar que pueda ser seleccionado por otro proceso. Una vez que el marco está limpio, esto es, que la página que contenía se ha pasado a disco, se planifica la página a ser copiada de memoria al marco, se actualizan las tablas de página y se restaura el contador de programa y los registros para que una vez que se pase el proceso al estado preparado para ejecución se carge su contexto y continúe la ejecución desde el punto en que se interrumpió.

Conjunto de trabajo de un proceso

Los programas que se ejecutan en un computador cumplen el principio de localidad de referencias, también denominado principio de proximidad, que afirma que durante un determinado intervalo de tiempo de ejecución de un proceso éste referencia direcciones virtuales próximas entre sí, esto es, páginas cercanas. Este conjunto de páginas forma una zona de localidad del proceso.

Así, el conjunto de trabajo de un proceso en el instante ti de tiempo virtual es el conjunto de páginas distintas que el proceso ha referenciado en sus últimas δ referencias a memoria principal. El tiempo virtual es el tiempo que un proceso está siendo ejecutado en el procesador.

Si se elige un valor de δ muy pequeño el conjunto de trabajo no cubrirá toda la zona de localidad actual si se elije muy grande se cubrirá más de una zona de localidad.

En la práctica, para reducir la sobrecarga se construye el conjunto de trabajo periodicamente cada cierto tiempo virtual Δ. Para ello se revisa el campo referenciada (bit r) de cada entrada de la tabla de páginas del proceso. El conjunto de trabajo está formado por todas aquellas páginas que tengan el bit r activado. Una vez construido, se pone r a cero.

Así puede definirse el conjunto de trabajo de un proceso como el conjunto de páginas distintas que el proceso en ejecución ha referenciado en el intervalo de tiempo virtual.

Dos conclusiones interesantes son:

• Una página miembro de un conjunto de trabajo no debe ser seleccionada como página víctima para ser reemplazada ya que provocaría un nuevo fallo de página.

• Un proceso debe tener asignados el suficiente número de marcos para poder tener cargado en memoria su conjunto de trabajo. En otro caso estará provocando continuamente fallso de página produciendo el fenómeno de sobrepaginación o trasiego (thrashing)

Reemplazamiento de páginas

El reemplazamiento de páginas consiste en seleccionar una página k cargada en un marco j de memoria principal para ser reemplezada por la página i a la que hacía referencia la dirección virtual que produjo el fallo de página. La página seleccionada para ser reemplazada se denomina página

víctima. El conjunto de marcos candidatos hace referencia a los marcos de memoria principal donde

se encuentran almacenadas las páginas candidatas a ser reemplazadas.

Estrategia de reemplazamiento de páginas local, cuando el conjunto de páginas candidatas a

ser reemplazadas pertenecen al mismo proceso que provocó el fallo.

Estrategia de reemplazamiento de páginas global, cuando el conjunto de páginas candidatas

está formado por todas las páginas cargadas en memoria principal en marcos no bloqueados. La estrategia de reemplazamiento local es más fácil de analizar, pero su implementación es más complicada y produce mayor sobrecarga.

Es deseable que el algoritmo de reemplazamiento disminuya el número de fallos de página a medida que aumenta el número de marcos de página de la memoria principal. Si esto no sucede se dice que el algortimo pacede la anomalía de Belady. El alogirtmo FIFO sufre de esta anomalía.

Algoritmo de reemplazamiento óptimo

Selecciona para ser reemplazada la página del conjunto de páginas candidatas a ser reemplazada que tardará más en volver a ser referenciada. Esto obliga a conocer con antelación qué direcciones virtuales van a ser referenciadas, pero esto no es posible y de ahí que este algoritmo no pueda ser implementador en la práctica pero sí sirve como referencia para comparar con otros algoritmos.

Algortimo de reemplazamiento LRU

El algoritmo de reemplazamiento de la página usada menos recientemente o algoritmo LRU (Least Recently Used) selecciona para ser reemplazada la página del conjunto de páginas candidatas que lleva más tiempo sin ser referenciada.

Este algoritmo es bastante bueno pero de implementación compleja. Produce bastante sobrecarga. Suele implementarse mediante una lista en la que cada entrada contiene el número de página del conjunto de páginas a ser reemplazada. Cada vez que una página es referenciada se coloca al principio de la lista y al final la página menos referenciada, esto es, la candidata a ser sustituida. Cada vez que se referencia una dirección virtual la lista debe ser reordenada.

Otra implementación se basa en un contador hardware que se incrementa cada vez que se referencia una dirección. En la tabla de páginas se añade un campo que almacena ese valor cuando una página es referenciada. De este modo, se selecciona para reemplazar la página que contenga el menor valor en ese campo.

Algoritmo de reemplazamiento mediente envejecimiento

El algoritmo de reemplazamiento mediante envejecimiento (aging) es una aproximación al algoritmo LRU pero que introduce menor sobrecarga ya que puede impelmentarse de forma más eficiente.

Se utiliza un registro de desplazamiento de n bits, inicialmente a cero. Cada cierto tiempo T el contenido del registro se desplaza a la derecha y se carga en el bit más significativo el bit

referenciada, r, después este bit se pone a cero. De este modo, la página a ser reemplazada es la que

tenga un menor valor en el registro.

El tamaño del registro determina la edad máxima que puede registrarse, ya que en un registro de 8 bits, todos a cero, no se puede determinar si la página no se ha referenciado en un tiempo ≥ 8T o se acaba de cargar.

Algoritmo de reemplazamiento FIFO

El algoritmo de reemplazamiento FIFO selecciona para ser reemplazada aquella página del conjunto de páginas candidatas a ser reemplazadas que lleva más tiempo cargada en memoria principal.

Para ello, el sistema mantiene una lista enlazada o cola FIFO en la que cada entrada contiene el número de página de una página del conjunto de páginas candidatas a ser reemplazadas. Cuando una página se carga en memoria se coloca al final de la lista. Así, la página que se encuentre en la cabeza de la lista indica la página que lleva más tiempo cargada en memoria y será la elegida para ser reemplazada.

La gestión de este algoritmo requiere muy poco tiempo de proceso. Es el más sencillo de programar y de implementar, pero no tiene una buena tasa de aciertos y además pacede la anomalíua de Belady.

Algoritmo de reemplazamiento de la segunda oportunidad (algoritmo del reloj)

Es una variante del algortimo FIFO que busca la página que lleva más tiempo cargada en memoria y no ha sido referenciada recientemente.

Básicamente se consulta el bit referenciada, r, de la página que se encuentra al principio de la cola FIFO, si r es cero, entonces es seleccionada para ser reemplazada. Si r es 1, se pone a cero y se envía la página al final de la cola.

Se obtiene un mejor rendimiento que con FIFO pero a costa de mayor sobrecarga, ya que hay que estar moviendo elementos en la cola.

Una forma de disminuir la sobrecarga es utilizar una lista o cola circular, así el puntero índice de cola es quien se mueve y no los elementos de la cola.

En este caso el algoritmo recibe el nombre de algoritmo del reloj.

Si además del bit referenciada se tiene en cuenta el bit modificada, m, se mejora sustancialmente la efectividad. En este caso nos encontramos con varias posibilidades.

• r = 0 y m = 0. Página no referenciada recientemente y no modificada, candidata ideal para ser reemplazada.

• r = 0 y m = 1. Página no referenciada recientemente pero modificada. De ser elegida es preciso actualizar la página en la memoria de intercambio.

• r = 1 y m = 0. Ha sido referenciada recientemente, por lo que no es buena candidata.

• r = 1 y m = 1. Ha sido referenciada y modificada recientemente, por lo que es probable que vuelva a ser referenciada y, además, es preciso actualizarla en memoria de intercambio. Con estas premisas, el algoritmo del reloj busca en primer lugar, a partir de la posición del puntero, una página se busca una página con r = 0 y m = 0, si no se encuentra se busca entonces alguna con r = 0 y m = 1, pero actualiza todos los r = 1 y los pone a cero. Si no encuentra ninguna vuelve a buscar r = 0 y m = 0, de no encontrarla por cuarta vez busca una página con r = 0 y m = 1, con la seguridad de que ahora sí tendrá éxito ya que en la segunda ronda todos los r se pusieron a cero.

Algoritmo de reemplazamiento del reloj considerando el conjunto de trabajo

El algoritmo del reloj puede ser mejorado si se considera el conjunto de trabao de un proceso. A este algoritmo resultante se le conoce con el nombre de algoritmo WSClock.

En este caso, cada entrada i de la página de un proceso debe tener un campo denominado tiempo de

último uso, que contiene el tiempo virtual de último uso de la página. Cuando se produce un fallo de

página se examina el bit r y si está a 1, se escribe en ese campo el tiempo virtual del proceso.

La diferencia del tiempo virtual del proceso con el tiempo almacenado nos da la edad del proceso. Siendo Δ el intervalo del conjunto de trabajo, si la edad de la página es mayor que Δ, no pertenece al conjunto de trabajo.

El algoritmo WSClock busca páginas con r = 0 y m = 0 y que no pertenezcan al conjunto de trabajo del proceso. Si durante una vuelta completa se da la situación de que todas las páginas pertenecen al conjunto de trabajo del proceso, entonces seleccionará la primera página que encuentre con r = 0 y m = 0, aunque pertenezca al conjunto de trabajo.

Conclusiones sobre los algoritmos de reemplazamiento

Los algoritmos más utilizados por los sistemas operativos modernos son el de envejecimiento y el WSClock.

La estragegia de reemplazo limita los algoritmos de reemplazamiento a utilizar. Así, algoritmos como FIFO, LRU y envejecimiento pueden utilizarse tanto con estrategia de reemplazo global o local.

El algoritmo WSClock sólo puede utilizarse con estrategia de reemplazo local.

Asignación de memoria principal

Esta tarea consiste básicamente en decidir cuántos marcos de página de la memoria principal se reserva para un proceso que se tiene que ejecutar.

Se deben reservar como mínimo los marcos suficientes para contener todas las páginas a las que pueda referenciar cualquier instrucción del repertorio de la máquina.

Como máximo, en teoría, se pueden asignar a un proceso todos aquellos que no estuvieran bloqueados, pero esto anula los beneficios de la multiprogramación.

Dos estrategias de asignación son:

Asignación fija. Consistente en asignar a cada proceso un número fijo de marcos. El

principal inconveniente es que si el conjunto de trabajo del proceso crece por encima del número de marcos asignados se producirá sobrepaginación aunque existan marcos libres en memoria. Si el conjunto de trabajo disminuye, por debajo del número de marcos asignados, se estaría desperdiciando memoria. Si el sistema operativo utiliza estrategia de asignación fija, es obligado que la estrategia de reemplazo sea local.

Asignación variable. Modifica a lo largo del tiempo el número de marcos que un proceso

tiene asignados. Minimiza la memoria desperdiciada y la sobrepaginación a costa de aumentar la sobrecarga ya que el sistema debe decidir continuamente cuántos marcos reservar a cada proceso.

Para implementar la asignación variable, que proporciona mejores resultados, se debe utilizar un algoritmo de asignación de marcos, siendo los más conocidos:

Algoritmo de asignación equitativa. Cada cierto tiempo se comprueba el número de

procesos en ejecución y se asigna a cada uno el mismo número de marcos.

Algortimo de asignación proporcional. Se asigna a cada proceso un número de marcos

proporcional a su tamaño y/o su prioridad.

Algoritmo de asignación por la frecuencia de fallos de página o algoritmo PFF. Se basa en

que cuanto mayor sea el número de marcos asignado a un proceso menor será su tasa de fallos, siempre que el algoritmo de reemplazamiento no sufra la anomalía de Belady.

Si la tasa de fallos se encuentra por encima de cierto límite, se asignan más marcos al proceso. Si la tasa de fallos cae por debajo de un límite inferior se le quitan marcos. Si la tasa de fallos está por encima del límite pero no existen marcos libres será necesario

Documento similar