Almacenamiento Virtual


2  ALMACENAMIENTO VIRTUAL

En el capítulo de manejo de memoria, se consideró que para que un proceso pueda ser ejecutado, éste debe estar cargado completamente en la memoria principal de la máquina. Esta restricción, parece necesaria y razonable, pero limita el tamaño de los programas a ejecutar al tamaño de la memoria física.

En realidad, examinando programas típicos reales, se llega a la conclusión de que en muchos casos no es necesario cargar el programa completo en memoria. Por ejemplo.

Aún en el caso en el que el programa entero sea ejecutado, es posible que no sea necesario cargarlo completo a un mismo tiempo.

La habilidad de ejecutar un programa que está parcialmente en memoria puede traer muchos beneficios. Por ejemplo.

 

En general, correr un programa que no está enteramente en memoria, beneficiaría tanto al sistema como al usuario.

Existen dos técnicas que permiten realizar esto: Overlays y Memoria Virtual.

   

2.1  SOBREPOSICION. "OVERLAYS".

Es una técnica que permite a un programa ser más grande que

la cantidad de memoria otorgada a él, sobreponiendo en una misma área de memoria dos o más subprogramas que no se usan al mismo tiempo, ni se llaman entre sí.

Cuando se escribe un programa con overlays, el lenguaje que se use debe tener esa capacidad, tal es el caso de algunos pascales como el turbo pascal 3.0. Ejemplo.

Considere dos subprogramas escritos en pascal: Procedure uno y procedure dos, los cuales son llamados por un programa principal cuyo nombre es prueba. El programa completo nos queda:

                                       PROGRAM PRUEBA;

                                       VAR (*Variables del programa prueba*)

                                           -

                                           -

 

                                       PROCEDURE UNO;

                                        BEGIN

                                           -

                                           -

                                        END;

 

                                       PROCEDURE DOS;

                                        BEGIN

                                           -

                                           -

                                        END;

 

                                       BEGIN (*Programa prueba*)

                                           -

                                           -

                                           -

                                       END. (*Programa prueba*)

 

El archivo compilado queda formado como se ilustra en la siguiente figura.

  ARCHIVO prueba.com

Si por ejemplo, el código del programa principal (prueba) ocupa 100 K y los procedimientos uno y dos ocupan 30 y 50 K respectivamente, y la memoria asignada al usuario es de solo 150 K, es obvio que el programa no podrá ser corrido.

Sin embargo, si los procedimientos uno y dos no se llaman entre ellos, se puede cargar solo uno de ellos a la vez junto con el programa principal. Esto se haría de la siguiente manera:

                                       PROGRAM PRUEBA;

                                       VAR

                                       (*variables del programa prueba*)

                                             -

                                             -

                                             -

                                       OVERLAY PROCEDURE UNO;

                                        BEGIN

                                             -

                                             -

                                             -

                                        END;

                                       OVERLAY PROCEDURE DOS;

                                         BEGIN

                                             -

                                             -

                                             -

                                         END;

                                       BEGIN (*Programa prueba*)

                                             -

                                             -

                                       END. (*Programa prueba*)

 

Lo anterior crea el mismo archivo prueba pero sin el códigode los dos subprogramas y un archivo más llamado prueba.000 (archivo de overlay) con el contenido de ambos subprogramas.

El programa es cargado a memoria colocando el código del archivo prueba, y dejando un hueco reservado para cargar el código de un subprograma u otro contenido en el archivo de overlay. Esto se ilustra en la siguiente figura.

El área de overlay es del tamaño del más grande de los overlays. Por lo tanto, al correr el programa, sólo el código de uno de los subprogramas es cargado a la vez en la misma área de memoria, permitiendo correr el programa como si estuviera cargado en memoria totalmente. Tiene la desventaja que el programa corre un poco más lento por tener que ir a disco (principalmente si es diskette).

 

2.2  MEMORIA VIRTUAL EN PAGINACION

Es una técnica que permite ejecutar programas que no están enteramente cargados en memoria, dando al usuario la impresión de que tiene una memoria mucho mayor a la memoria física de la máquina, por lo que puede escribir pogramas muy extensos. La memoria virtual en paginación está constituida por dos subsistemas: El demandador de páginas y el algoritmo de remplazo de página.

 

DEMANDADOR DE PAGINAS

En  el demandador de páginas, en lugar de cargar en memoria todas las páginas que componen el programa, como se hacía en el equema de paginación visto anteriormente, las páginas se van cargando según lo vaya requiriendo la ejecución de éste; es decir, que una página nunca será cargada a memoria a menos que sea necesaria.

Sin embargo, cuando el CPU trata de usar una página que no ha sido traída a memoria, traduce una dirección de usuario en una dirección física utilizando la tabla de páginas, pero como esta dirección no tiene un cuadro asociado, entonces la dirección es inválida y se genera un error abortando el programa.

Para evitar este problema, el hardware de paginación es modificado agregando un bit de validación. De esta manera, si una página no ha sido traída a memoria, el bit es puesto a 1 ó inválido. Esto se ilustra en la figura.

 

De esta manera, cuando se accesa la tabla de páginas, es posible saber si la página está en memoria ó no. Si la página no está cargada en memoria, en lugar de producir una interrupción al sistema operativo del tipo de dirección de memoria ilegal, la cual abortaría el programa, ahora se genera una interrupción de otro tipo indicando que la página no está en memoria.  El manejador de esta interrupción procederá a cargar la página faltante y proseguirá la ejecución del programa. Esto se ilustra en la siguiente figura.

El procediminto se resume en los siguientes puntos.

1.- Primero checamos la tabla interna mantenida en el bloque de control de proceso, para determinar si la referencia es un acceso a memoria válido o inválido. Si fue inválido, abortar el programa.

2.- Si fue una referencia válida pero aún no hemos traído la  página, debemos traerla ahora.

3.- Encontrar un cuadro libre (buscando en la lista de cuadros  disponibles), y determinar en qué lugar en disco se  encuentra la página faltante.

4.- Hacer una operación de lectura para traer la página deseada  al cuadro nuevo asignado.

5.- Cuando la lectura se haya completado, modificar la tabla  interna y la tabla de páginas para reflejar que la página  está ahora en memoria.

6.- Restablecer la instrucción que fue interrumpida por la página faltante. El proceso puede ahora accesar la página como si siempre hubiera estado en memoria.

Hay que hacer notar que al generarse la interrupción, es necesario guardar el estado del proceso interrumpido (registros, código de condiciones,  contador del programa)  en su PCB correspondiente, de tal  manera que el  proceso pueda ser restablecido después de haber traído la página faltante.

En el caso extremo, nosotros podemos empezar la ejecución de un  programa  con  cero páginas  en  memoria. El  proceso inmediatamente generará una petición de página con la primera instrucción. Después de que esta página sea traída, el programa continuará ejecutándose y generando peticiones de páginas (como sea necesario) hasta que cada página que sea necesaria esté en memoria. En este  punto, el programa puede ejecutarse sin interrupciones de falta de páginas, o bien la frecuencia de falta de páginas puede mantenerse en un nivel razonablemente bajo. Se estima que este nivel debe ser del orden de un acceso de memoria en 100000. De no ser así, la ejecución de los programas se alenta dramáticamente debido al tiempo total transcurrido desde que se genera la interrupción, se checa si es una página faltante, determina la posición de la página en disco, se lee y escribe en un  cuadro libre, actualiza  la tabla y se restablece la instrucción interrumpida. Este tiempo en promedio es del orden de 10 milisegundos.

Se ha dicho que uno de los principales beneficios de no cargar completamente los programas, es que nos queda más memoria disponible y por lo tanto más usuarios pueden ser cargados al mismo tiempo, aumentando el grado de multiprogramación.

Por ejemplo si tenemos 40 cuadros de memoria física y un programa que tiene 10 páginas pero solo usa realmente 5, podríamos cargar hasta 8 programas similares en lugar de 4 si no tuviéramos memoria virtual.

Sin embargo, sí repentinamente los ocho programas requirieran usar las 10 páginas completas se tendría una demanda de 80 cuadros cuando solamente se tienen 40.

Aunque esta situación es poco probable, ésta llega a ser muy factible cuando aumentamos el grado de multiprogramación, al punto en que la memoria promedio de uso, se aproxima a la memoria física disponible.

Cuando esta situación se presenta, el sistema operativo tiene varias opciones:

1.- Abortar el programa en cuestión. Sin embargo dado que la idea de usar memoria virtual es beneficiar tanto al usuario como al sistema, es obvio que ésta no es la mejor opción.

2.- Reducir el grado de multiprogramación, pasando a disco a uno de los usuarios (swapping) y liberando así todos sus cuadros de memoria que ocupaba. Esta es una buena solución más no la mejor.

3.- La mejor opción, es utilizar un algoritmo llamado remplazo de página (page replacement).

 

ALGORITMO DE REMPLAZO DE PAGINA

El funcionamiento de este algoritmo es el siguiente:

Si no hay un cuadro libre, encontrar uno que no se estéusando y desocuparlo escribiendo su contenido a disco, y reflejando el cambio en la tabla de páginas para indicar que esa página no está más en memoria.

El cuadro libre puede ahora ser utilizado para cargar la página faltante. Esto se ilustra en la siguiente figura.

 

Al introducir el algoritmo de remplazo de página, la rutina del sistema operativo que sirve la interrupción de una página faltante queda como sigue:

1.- Encontrar la localización en disco de la página deseada.

 2.- Encontrar un cuadro libre

               Si hay un cuadro, entonces: usarlo

               Sino:   Usar un algoritmo de remplazo de página para encontrar un cuadro

                            víctima.

               Escribir la página víctima al disco.

                            Actualizar la  tabla de páginas para reflejar el cambio.

               [Fin del condicional]

 3.- Leer la página faltante y escribirla en el cuadro libre.

     Cambiar la tabla de páginas.

4.- Restablecer la ejecución del programa.

 Note que dos intercambios (swappings) son requeridos si no hay cuadros libres. Esta situación dobla el tiempo de servicio de una página faltante. Si esto es muy frecuente, el funcionamiento del sistema puede no ser muy eficiente, por tanto el grado de

multiprogramación debe ser escogido adecuadamente.

La combinación del demandador de páginas con el remplazador de páginas, es la manera en que comúnmente se implementa la memoria virtual, la cual constituye una separación de la memoria lógica de  la memoria física. La memoria virtual puede ser mucho más grande que la memoria física.

     

2.3  MEMORIA VIRTUAL EN SEGMENTACION

La memoria virtual también puede ser implementada en sistemas de segmentación; sin embargo requiere de algoritmos de remplazo más complejos.

Resulta más fácil implementar memoria virtual segmentada a través de sistemas de segmentación paginada; es decir, los segmentos divididos en páginas. De esta forma, el usuario ve un sistema segmentado, pero el S. O. ve un sistema paginado, por lo que puede utilizar el algoritmo de remplazo de página.


Regresar al menú principal