Make your own free website on Tripod.com
Sistemas Operativos
Administración de la Memoria
Home
Red Wireless
Introducción
Definiciones
Historia de los S.O.
Tipos de S.O.
Tipos de Archivos
Administración de la Memoria
Administración de Procesos
Manejo de Entrada y Salida
Nucleos de Sistemas Operativos
Caso de Estudio: UNIX
Caso de Estudio: VMS
Caso de Estudio: OS/2
Caso de Estudio: Windows NT

4. ADMINISTRACION DE LA MEMORIA

                                                          

En esta sección se describirán las técnicas más usuales en el manejo de memoria, revisando los conceptos relevantes. Se abarcarán los esquemas de manejo simple de memoria real, la multiprogramación en memoria real con sus variantes, el concepto de `overlays', la multiprogramación con intercambio y los esquemas de manejo de memoria virtual.

4.1. Panorama general

Un vistazo al material que se va a cubrir en esta sección se muestra en la figura 4.1. Es una gráfica en donde se especifican, en términos generales, los conceptos más importantes en cuanto a las técnicas empleadas en el manejo de memoria.

4.2. Manejo de memoria en sistemas monousuario sin intercambio

Este esquema es aún muy frecuente en México y se usa principalmente en sistemas monousuario y monotarea, como son las computadoras personales con DOS. Bajo este esquema, la memoria real es tomada para almacenar el programa que se esté ejecutando en un momento dado, con la visible desventaja de que si se está limitado a la cantidad de RAM disponible únicamente. La organización física bajo este esquema es muy simple: El sistema operativo se ubica en las localidades superiores o inferiores de la memoria, seguido por algunos manejadores de dispositivos ( `drivers' ). Esto deja un espacio contiguo de memoria disponible que es tomado por los programas del usuario, dejando generalmente la ubicación de la pila (` stack' ) al último, con el objetivo de que ésta pueda crecer hasta el máximo posible. Estas diferentes opciones se pueden ver en la figura 4.2. Como es obvio, bajo estos esquemas no se requieren algoritmos sofisticados para asignar la memoria a los diferentes procesos, ya que éstos son ejecutados secuencialmente conforme van terminando.

4.3. Multiprogramación en memoria real

En los 60's, las empresas e instituciones que habían invertido grandes sumas en la compra de equipo de cómputo se dieron cuenta rápidamente que los sistemas en lote invertían una gran cantidad de tiempo en operaciones de entrada y salida, donde la intervención de la unidad central de procesamiento era prácticamente nula, y se comenzaron a preguntar cómo hacer que se mantuviera más tiempo ocupada. Fue así como nació el concepto de multiprogramación, el cual consiste en la idea de poner en la memoria física más de un proceso al mismo tiempo, de manera que si el que se está ejecutando en este momento entraba en un periodo de entrada/salida, se podia tomar otro proceso para que usara la unidad central de procesamiento. De esta forma, la memoria fisica se dividía en secciones de tamaño suficiente para contener a varios programas.

De esta manera, si un sistema gastaba en promedio 60% de su tiempo en entrada/salida por proceso, se podía aprovechar más el CPU. Anterior a esto, el CPU se mantenía ese mismo porcentaje ocioso; con la nueva técnica, el tiempo promedio ocioso disminuye de la siguiente forma. Llámese al tiempo promedio que el CPU está ocupado `grado de multiprogramación'. Si el sistema tuviese un solo proceso siempre, y éste gastara 60% en entrada/salida, el grado de multiprogramación sería 1 - 60% = 40% = 0.4. Con dos procesos, para que el CPU esté ocioso se necesita que ambos procesos necesiten estar haciendo entrada/salida, es decir, suponiendo que son independientes, la probabilidad de que ambos estén en entrada/salida es el producto de sus probabilidades, es decir, 0.6x0.6 = 0.36. Ahora, el grado de multiprogramación es 1 - (probabilidad de que ambos procesos estén haciendo entrada/salida) = 1 - 0.36 = 0.64.

Como se ve, el sistema mejora su uso de CPU en un 24% al aumentar de uno a dos procesos. Para tres procesos el grado de multiprogramación es 1 - (0.6) 3 = 0.784, es decir, el sistema está ocupado el 78.4% del tiempo. La fórmula del grado de multiprogramación, aunque es muy idealista, pudo servir de guía para planear un posible crecimiento con la compra de memoria real, es decir, para obtener el punto en que la adición de procesos a RAM ya no incrementa el uso de CPU.

Dentro del esquema de multiprogramación en memoria real surgieron dos problemas interesantes: la protección y la relocalización.

4.3.1. El problema de la relocalización

Este problema no es exclusivo de la multiprogramación en memoria real, sino que se presentó aquí pero se sigue presentando en los esquemas de memoria virtual también. Este problema consiste en que los programas que necesitan cargarse a memoria real ya están compilados y ligados, de manera que internamente contienen una serie de referencias a direcciones de instrucciones, rutinas y procedimientos que ya no son válidas en el espacio de direcciones de memoria real de la sección en la que se carga el programa. Esto es, cuando se compiló el programa se definieron o resolvieron las direcciones de memoria de acuerdo a la sección de ese momento, pero si el programa se carga en otro dia en una sección diferente, las direcciones reales ya no coinciden. En este caso, el manejador de memoria puede solucionar el problema de dos maneras: de manera `estática' o de manera `dinámica'. La solución `estática' consiste en que todas las direcciones del programa se vuelvan a recalcular al momento en que el programa se carga a memoria, esto es, prácticamente se vuelve a recompilar el programa. La solución `dinámica' consiste en tener un registro que guarde la dirección base de la sección que va a contener al programa. Cada vez que el programa haga una referencia a una dirección de memoria, se le suma el registro base para encontrar la dirección real. Por ejemplo, suponga que el programa es cargado en una sección que comienza en la dirección 100. El programa hará referencias a las direcciones 50,52,54. Pero el contenido de esas direcciones no es el deseado, sino las direcciones 150, 152 y 154, ya que ahí comienza el programa. La suma de 100 + 50, ...,etcétera se hacen al tiempo de ejecución. La primera solución vale más la pena que la segunda si el programa contiene ciclos y es largo, ya que consumirá menos tiempo en la resolución inicial que la segunda solución en las resoluciones en línea.

4.3.2. El problema de la protección

Este problema se refiere a que, una vez que un programa ha sido caragado a memoria en algún segmento en particular, nada le impide al programador que intente direccionar ( por error o deliberadamente ) localidades de memoria menores que el límite inferior de su programa o superiores a la dirección mayor; es decir, quiere referenciar localidades fuera de su espacio de direcciones. Obviamente, este es un problema de protección, ya que no es legal leer o escribir en áreas de otros programas.

La solución a este problema también puede ser el uso de un registro base y un registro límite. El registro base contiene la dirección del comienzo de la sección que contiene al programa, mientras que el límite contiene la dirección donde termina. Cada vez que el programa hace una referencia a memoria se checa si cae en el rango de los registros y si no es así se envía un mensaje de error y se aborta el programa.

4.3.3. Particiones fijas o particiones variables

En el esquema de la multiprogramación en memroia real se manejan dos alternativas para asignarle a cada programa su partición correspondiente: particiones de tamaño fijo o particiones de tamaño variable. La alternativa más simple son las particiones fijas. Dichas particiones se crean cuando se enciende el equipo y permanecerán con los tamaños iniciales hasta que el equipo se apague. Es una alternativa muy vieja, quien hacía la división de particiones era el operador analizando los tamaños estimados de los trabajos de todo el día. Por ejemplo, si el sistema tenía 512 kilobytes de RAM, podia asignar 64 k para el sistema operativo, una partición más de 64 k, otra de 128k y una mayor de 256 k. Esto era muy simple, pero inflexible, ya que si surgían trabajos urgentes, por ejemplo, de 400k, tenían que esperar a otro día o reparticionar, inicializando el equipo desde cero. La otra alternativa, que surgió después y como necesidad de mejorar la alternativa anterior, era crear particiones contiguas de tamaño variable. Para esto, el sistema tenía que mantener ya una estructura de datos suficiente para saber en dónde habían huecos disponibles de RAM y de dónde a dónde habían particiones ocupadas por programas en ejecución. Así, cuando un programa requería ser cargado a RAM, el sistema analizaba los huecos para saber si había alguno de tamaño suficiente para el programa que queria entrar, si era así, le asignaba el espacio. Si no, intentaba relocalizar los programas existentes con el propósito de hacer contiguo todo el espacio ocupado, así como todo el espacio libre y así obtener un hueco de tamaño suficiente. Si aún así el programa no cabía, entonces lo bloqueaba y tomaba otro. El proceso con el cual se juntan los huecos o los espacios ocupados se le llama `compactación'. El lector se habrá dado cuenta ya de que surgen varios problemas con los esquemas de particiones fijas y particiones variables: ø En base a qué criterio se elige el mejor tamaño de partición para un programa ? Por ejemplo, si el sistema tiene dos huecos, uno de 18k y otro de 24 k para un proceso que desea 20 k, ø Cual se le asigna ? Existen varios algoritmos para darle respuesta a la pregunta anterior, los cuales se ennumeran y describen enseguida.

  • Primer Ajuste: Se asigna el primer hueco que sea mayor al tamaño deseado.
  • Mejor Ajuste: Se asigna el hueco cuyo tamaño exceda en la menor cantidad al tamaño deseado. Requiere de una búsqueda exhaustiva.
  • Peor Ajuste: Se asigna el hueco cuyo tamaño exceda en la mayor cantidad al tamaño deseado. Requiere también de una búsqueda exhaustiva.
  • El Siguiente Ajuste: Es igual que el `primer ajuste' con la diferencia que se deja un apuntador al lugar en donde se asignó el último hueco para realizar la siguiente búsqueda a partir de él.
  • Ajuste Rápido: Se mantienen listas ligadas separadas de acuerdo a los tamaños de los huecos, para así buscarle a los procesos un hueco más rápido en la cola correspondiente.

Otro problema que se vislumbra desde aquí es que, una vez asignado un hueco, por ejemplo, con "el peor ajuste", puede ser que el proceso requiriera 12 kilobytes y que el hueco asignado fuera de 64 kilobytes, por lo cual el proceso va a desperdiciar una gran cantidad de memoria dentro de su partición, lo cual se le llama `fragmentación interna'.

Por otro lado, conforme el sistema va avanzando en el día, finalizando procesos y comenzando otros, la memoria se va configurando como una secuencia contigua de huecos y de lugares asignados, provocando que existan huecos, por ejemplo, de 12 k, 28k y 30 k, que sumados dan 70k, pero que si en ese momento llega un proceso pidiéndolos, no se le pueden asignar ya que no son localidades contiguas de memoria ( a menos que se realice la compactación ). Al hecho de que aparezcan huecos no contiguos de memoria se le llama `fragmentación externa'.

De cualquier manera, la multiprogramación fue un avance significativo para el mejor aprovechamiento de la unidad central de procesamiento y de la memoria misma, así como dio pie para que surgieran los problemas de asignación de memoria, protección y relocalización, entre otros.

4.3.4. Los overlays

Una vez que surgió la multiprogramación, los usuarios comenzaron a explorar la forma de ejecutar grandes cantidades de código en áreas de memoria muy pequeñas, auxiliados por algunas llamadas al sistema operativo. Es así como nacen los `overlays'.

Esta técnica consiste en que el programador divide lógicamente un programa muy grande en secciones que puedan almacenarse el las particiones de RAM. Al final de cada sección del programa ( o en otros lugares necesarios ) el programador insertaba una o varias llamadas al sistema con el fin de descargar la sección presente de RAM y cargar otra, que en ese momento residía en disco duro u otro medio de almacenamiento secundario. Aunque esta técnica era eficaz ( porque resolvía el problema ) no era eficiente ( ya que no lo resolvía de la mejor manera ). Esta solución requería que el programador tuviera un conocimiento muy profundo del equipo de cómputo y de las llamadas al sistema operativo. Otra desventaja era la portabilidad de un sistema a otro: las llamadas cambiaban, los tamaños de particiones también. Resumiendo, con esta técnica se podían ejecutar programas más grandes que las particiones de RAM, donde la división del código corría a cuenta del programador y el control a cuenta del sistema operativo.

4.4. Multiprogramación en memoria virtual

La necesidad cada vez más imperiosa de ejecutar programas grandes y el crecimiento en poder de las unidades centrales de procesamiento empujaron a los diseñadores de los sistemas operativos a implantar un mecanismo para ejecutar automáticamente programas más grandes que la memoria real disponible, esto es, de ofrecer `memoria virtual'.

La memoria virtual se llama así porque el programador ve una cantidad de memoria mucho mayor que la real, y en realidad se trata de la suma de la memoria de almacenamiento primario y una cantidad determinada de almacenamiento secundario. El sistema operativo, en su módulo de manejo de memoria, se encarga de intercambiar programas enteros, segmentos o páginas entre la memoria real y el medio de almacenamiento secundario. Si lo que se intercambia son procesos enteros, se habla entonces de multiprogramación en memoria real, pero si lo que se intercambian son segmentos o páginas, se puede hablar de multiprogramación con memoria virtual.

La memoria virtual se apoya en varias técnicas interesantes para lograr su objetivo. Una de las teorias más fuertes es la del `conjunto de trabajo', la cual se refiere a que un programa o proceso no está usando todo su espacio de direcciones en todo momento, sino que existen un conjunto de localidades activas que conforman el `conjunto de trabajo'. Si se logra que las páginas o segmentos que contienen al conjunto de trabajo estén siempre en RAM, entonces el programa se desempeñará muy bien.

Otro factor importante es si los programas exhiben un fenómeno llamado `localidad', lo cual quiere decir que algunos programas tienden a usar mucho las instrucciones que están cercanas a la localidad de la instrucción que se está ejecutando actualmente.

4.4.1 Paginación pura

La paginación pura en el majejo de memoria consiste en que el sistema operativo divide dinámicamente los programas en unidades de tamaño fijo ( generalmente múltiplos de 1 kilobyte ) los cuales va a manipular de RAM a disco y viceversa. Al proceso de intercambiar páginas, segmentos o programas completos entre RAM y disco se le conoce como `intercambio' o `swapping'. En la paginación, se debe cuidar el tamño de las páginas, ya que si éstas son muy pequeñas el control por parte del sistema operativo para saber cuáles están en RAM y cuales en disco, sus direcciones reales, etc; crece y provoca mucha `sobrecarga' (overhead). Por otro lado, si las páginas son muy grandes, el overhead disminuye pero entonces puede ocurrir que se desperdicie memoria en procesos pequeños. Debe haber un equilibrio.

Uno de los aspectos más importantes de la paginación, asi como de cualquier esquema de memoria virtual, es la forma de traducir una dirección virtual a dirección real. Para explicarlo, obsérvese la figura 4.3.

Como se observa, una dirección virtual `v' = ( b,d) está formada por un número de página virtual `b' y un desplazamiento `d'. Por ejemplo, si el sistema ofrece un espacio de direcciones virtuales de 64 kilobytes, con páginas de 4 kilobytes y la RAM sólo es de 32 kilobytes, entonces tenemos 16 páginas virtuales y 8 reales. La tabla de direcciones virtuales contiene 16 entradas, una por cada página virtual. En cada entrada, o registro de la tabla de direcciones virtuales se almacenan varios datos: si la página está en disco o en memoria, quién es el dueño de la página, si la página ha sido modificada o es de lectura nada mas, etc. Pero el dato que nos interesa ahora es el número de página real que le corresponde a la página virtual. Obviamente, de las 16 virtuales, sólo ocho tendrán un valor de control que dice que la página está cargada en RAM, así como la dirección real de la página, denotada en la figura 4.3 como b' . Por ejemplo, supóngase que para la página virtual número 14 la tabla dice que, efectivamente está cargada y es la página real 2 ( dirección de memoria 8192 ). Una vez encontrada la página real, se le suma el desplazamiento, que es la dirección que deseamos dentro de la página buscada ( b' + d ).

La tabla de direcciones virtuales a veces está ubicada en la misma meoria RAM, por lo cual se necesita saber en qué dirección comienza, en este caso, existe un registro con la dirección base denotada por la letra `a' en la figura 4.3.

Cuando se está buscando una página cualquiera y ésta no está cargada, surge lo que se llama un `fallo de página' (page fault ). Esto es caro para el manejador de memoria, ya que tiene que realizar una serie de pasos extra para poder resolver la dirección deseada y darle su contenido a quien lo pide. Primero, se detecta que la página no está presente y entonces se busca en la tabla la dirección de esta página en disco. Una vez localizada en disco se intenta cargar en alguna página libre de RAM. Si no hay páginas libres se tiene que escoger alguna para enviarla hacia el disco. Una vez escogida y enviada a disco, se marca su valor de control en la tabla de direcciones virtuales para indicar que ya no está en RAM, mientras que la página deseada se carga en RAM y se marca su valor para indicar que ahora ya está en RAM. Todo este procedimiento es caro, ya que se sabe que los accesos a disco duro son del orden de decenas de veces más lentos que en RAM. En el ejemplo anterior se mencionó que cuando se necesita descargar una página de RAM hacia disco se debe de hacer una elección. Para realizar esta elección existen varios algoritmos, los cuales se describen enseguida. _ La primera en entrar, primera en salir: Se escoge la página que haya entrado primero y esté cargada en RAM. Se necesita que en los valores de control se guarde un dato de tiempo. No es eficiente porque no aprovecha ninguna característica de ningún sistema. Es justa e imparcial. _ La no usada recientemente: Se escoge la página que no haya sido usada (referenciada) en el ciclo anterior. Pretende aprovechar el hecho de la localidad en el conjunto de trabajo.

  • La usada menos recientemente: Es parecida a la anterior, pero escoge la página que se usó hace más tiempo, pretendiendo que como ya tiene mucho sin usarse es muy probable que siga sin usarse en los próximos ciclos. Necesita de una búsqueda exhaustiva.
  • La no usada frecuentemente: Este algoritmo toma en cuenta no tanto el tiempo, sino el número de referencias. En este caso cualquier página que se use muy poco, menos veces que alguna otra.
  • La menos frecuentemente usada: Es parecida a la anterior, pero aquí se busca en forma exhaustiva aquella página que se ha usado menos que todas las demás.
  • En forma aleatoria: Elige cualquier página sin aprovechar nada. Es justa e imparcial, pero ineficiente.

Otro dato interesante de la paginación es que ya no se requiere que los programas estén ubicados en zonas de memoria adyacente, ya que las páginas pueden estar ubicadas en cualquier lugar de la memoria RAM.

4.4.2 Segmentación pura

La segmentación se aprovecha del hecho de que los programas se dividen en partes lógicas, como son las partes de datos, de código y de pila (stack). La segmentación asigna particiones de memoria a cada segmento de un programa y busca como objetivos el hacer fácil el compartir segmentos ( por ejemplo librerías compartidas ) y el intercambio entre memoria y los medios de almacenamiento secundario.

Por ejemplo, en la versión de UNIX SunOS 3.5, no existían librerías compartidas para algunas herramientas, por ejemplo, para los editores de texto orientados al ratón y menús. Cada vez que un usuario invocaba a un editor, se tenía que reservar 1 megabyte de memoria. Como los editores son una herramienta muy solicitada y frecuentemente usada, se dividió en segmentos para le versión 4.x ( que a su vez se dividen en páginas ), pero lo importante es que la mayor parte del editor es común para todos los usuarios, de manera que la primera vez que cualquier usuario lo invocaba, se reservaba un megabyte de memoria como antes, pero para el segundo, tercero y resto de usuarios, cada editor extra sólo consumía 20 kilobytes de memoria. El ahorro es impresionante. Obsérvese que en la segmentación pura las particiones de memoria son de tamaño variable, en contraste con páginas de tamaño fijo en la paginación pura. También se puede decir que la segmentación pura tiene una granularidad menor que la paginación por el tamanó de segmentos versus tamaño de páginas. Nuevamente, para comprender mejor la segmentación, se debe dar un repaso a la forma en que las direcciones virtuales son traducidas a direcciones reales, y para ellos se usa la figura 4.4. Prácticamente la traducción es igual que la llevada a cabo en la paginación pura, tomando en consideracióñ que el tamaño de los bloques a controlar por la tabla de traducción son variables, por lo cual, cada entrada en dicha tabla debe contener la longitud de cada segmento a controlar. Otra vez se cuenta con un registro base que contiene la dirección del comienzo de la tabla de segmentos. La dirección virtual se compone de un número de segmento (s) y un desplazamiento ( d ) para ubicar un byte (o palabra ) dentro de dicho segmento. Es importante que el desplazamiento no sea mayor que el tamaño del segmento, lo cual se controla simplemente checando que ese valor sea mayor que la dirección del inicio del segmento y menor que el inicio sumado al tamaño.

Una ves dada una dirección virtual v=( s,d ), se realiza la operación b + s para hallar el registro (o entrada de la tabla de segmentos ) que contiene la dirección de inicio del segmento en la memoria real, denotado por s'. Ya conociendo la dirección de inicio en memoria real s' sólo resta encontrar el byte o palabra deseada, lo cual se hace sumándole a s' el valor del desplazamiento, de modo que la dirección real ® r = s' + d.

Cada entrada en la tabla de segmentos tiene un formato similar al mostrado en la figura 4.5. Se tienen campos que indican la longitud, los permisos, la presencia o ausencia y dirección de inicio en memoria real del segmento.

Según amplios experimentos [Deitel93] sugieren que un tamaño de páginas de 1024 bytes generalmente ofrece un desempeño muy aceptable. Intuitivamente parecería que el tener páginas del mayor tamaño posible haría que el desempeño fuera óptimo pero no es así, a menos que la página fuera del tamaño del proceso total. No es así con tamaños grandes de página menores que el proceso, ya que cuando se trae a memoria principal una página por motivo de un solo byte o palabra, se están trayendo muchísimos más bytes de los deseados. La dependencia entre el número de fallas respecto al tamaño de las páginas se muestra en la figura 4.6.

Un hecho notable en los sistemas que manejan paginación es que cuando el proceso comienza a ejecutarse ocurren un gran número de fallos de página, porque es cuando está referenciando muchas direcciones nuevas por vez primera, después el sistema se estabiliza, conforme el número de marcos asignados se acerca al tamaño del conjunto de trabajo.

El la figura 4.7 se muestra la relación entre el tiempo promedio entre fallas de página y el número de marcos de página asignados a un proceso. Allí se ve que el tiempo entre fallas decrece conforme se le asignan más páginas al proceso. La gráfica se curva en un punto, el cual corresponde a que el proceso tiene un número de páginas asignado igual al que necesita para almacenar su conjunto de trabajo. Después de eso, el asignarle a un proceso más páginas que las de su conjunto de trabajo ya no conviene, ya que el tiempo promedio entre fallas permanece sin mucha mejora. Un aspecto curioso de aumentar el número de páginas a un proceso cuando el algoritmo de selección de páginas candidatas a irse a disco es la primera en entrar primera en salir es la llamada `anomalía FIFO' a `anomalía de Belady'. Belady encontró ejemplos en los que un sistema con un número de páginas igual a tres tenía menos fallas de páginas que un sistema con cuatro páginas. El ejemplo descrito en [Tanxx] es injusto. Si se mira con cuidado, obviamente si se compara un sistema con 10 páginas contra otro de 5, ya de inicio el primer sistema tendrá 5 fallos de página más que el de 5, porque se necesitan diez fallos para cargarlo. A esto debería llamársele `anomalía de Belady con corrección.

4.4.3 Sistemas combinados

La paginación y la segmentación puras son métodos de manejo de memoria bastante efectivos, aunque la mayoría de los sistemas operativos modernos implantan esquemas combinados, es decir, combinan la paginación y la segmentación. La idea de combinar estos esquemas se debe a que de esta forma se aprovechan los conceptos de la división lógica de los programas (segmentos) con la granularidad de las páginas. De esta forma, un proceso estará repartido en la memoria real en pequeñas unidades (páginas) cuya liga son los segmentos. También es factible así el compartir segmentos a medida que las partes necesitadas de los mismos se van referenciando (páginas). Para comprender este esquema, nuevamente se verá cómo se traduce una dirección virtual en una localidad de memoria real. Para la paginación y segmentacíon puras se puede decir que el direccionamiento es `bidimensional' porque se necesitan dos valores para hallar la dirección real. Para el caso combinado, se puede decir que se tiene un direccionamiento `tridimensional'. En la figura 4.8 [ Deitel93] se muestran las partes relevantes para lograr la traducción de direcciones. El sistema debe contar con una tabla de procesos (TP). Por cada renglón de esa tabla se tiene un número de proceso y una dirección a una tabla de segmentos. Es decir, cada proceso tiene una tabla de segmentos. Cuando un proceso hace alguna referencia a memoria, se consulta TP para encontrar la tabla de segmentos de ese proceso. En cada tabla de segmentos de proceso (TSP) se tienen los números de los segmentos que componen a ese proceso. Por cada segmento se tiene una dirección a una tabla de páginas. Cada tabla de páginas tiene las direcciones de las páginas que componen a un solo segmento. Por ejemplo, el segmento `A' puede estar formado por las páginas reales `a','b','c','p' y `x'. El segmento `B' puede estar compuesto de las páginas `f','g','j','w' y `z'.

Para traducir una dirección virtual v=(s,p,d) donde `s' es el segmento, `p' es la página y `d' el desplazamiento en la página se hace lo siguiente. Primero se ubica de qué proceso es el segmento y se localiza la tabla de segmentos de ese proceso en la TP. Con `s' como índice se encuentra un renglón ( registro) en la tabla de segmentos de ese proceso y en ese renglón está la dirección de la tabla de páginas que componen al segmento. Una vez en la tabla de páginas se usa el valor `p' como índice para encontrar la dirección de la página en memoria real. Una vez en esa dirección de memoria real se encuentra el byte (o palabra) requerido por medio del valor de `d'.

Ahora, en este esquema pueden haber dos tipos de fallos: por fallo de página y por fallo de segmento. Cuando se hace referencia a una dirección y el segmento que la contiene no está en RAM ( aunque sea parcialmente ), se provoca un fallo por falta de segmento [Deitel93] y lo que se hace es traerlo del medio de almacenamiento secundario y crearle una tabla de páginas. Una vez caragado el segmento se necesita localizar la página correspondiente, pero ésta no existe en RAM, por lo cual se provoca un fallo de página y se carga de disco y finalmente se puede ya traer la dirección deseada por medio del desplazamiento de la dirección virtual.

La eficiencia de la traducción de direcciones tanto en paginación pura, segmentación pura y esquemas combinados se mejora usando memorias asociativas para las tablas de páginas y segmentos, así como memorias cache para guardar los mapeos más solicitados.

Otro aspecto importante es la estrategia para cargar páginas ( o segmentos ) a la memoria RAM. Se usan más comunmente dos estrategias: cargado de páginas por demanda y cargado de páginas anticipada. La estrategia de caragdo por demanda consiste en que las páginas solamente son llevadas a RAM si fueron solicitadas, es decir, si se hizo referencia a una dirección que cae dentro de ellas. La carga anticipada consiste en tratar de adivinar qué páginas serán solicitadas en el futuro inmediato y cargarlas de antemano, para que cuando se pidan ya no ocurran fallos de página. Ese `adivinar' puede ser que se aproveche el fenómeno de localidad y que las páginas que se cargan por anticipado sean aquellas que contienen direcciones contiguas a la dirección que se acaba de refenciar. De hecho, el sistema operativo VMS usa un esquema combinado para cargar páginas: cuando se hace referencia a una dirección cuya página no está en RAM, se provoca un fallo de página y se carga esa página junto con algunas páginas adyacentes. En este caso la página solicitada se cargó por demanda y las adyacentes se cargaron por anticipación.

Profesor: Fernando Guerrero T.
Consultas (mensajes) al : 08-3619056