GESTIÓN DE MEMORIA, SEGMENTACIÓN Y PAGINACIÓN DE MICROPROCESADORES


GESTIÓN DE MEMORIA, SEGMENTACIÓN Y PAGINACIÓN


INTRODUCCIÓN :

  • Memoria es uno de los principales recursos del computador. Siempre existió el problema de falta de memoria.
  • La parte del sistema operativo que administra la memoria se llama administrador de memoria, y su labor consiste en llevar un registro de las partes de memoria que se estén utilizando y aquellas que no, con el fin de asignar espacio en memoria a los procesos cuando éstos la necesiten y liberándola cuando terminen, así como administrar el intercambio entre la memoria principal y el disco en los casos en los que la memoria principal no le pueda dar capacidad a todos los procesos que tienen necesidad de ella.
  • Los sistemas de administración de memoria se pueden clasificar en dos tipos: los que desplazan los procesos de la memoria principal al disco y viceversa durante la ejecución y los que no. 
  • El propósito principal de una computadora es el de ejecutar programas. (programas + info que accesan -> memoria principal)
  • Para optimizar el uso del CPU y de la memoria, el sistema operativo debe de tener varios procesos a la vez en la memoria principal, para lo cual dispone de varias opciones de administración tanto del procesador como de la memoria.
1.- GESTIÓN DE MEMORIA


1.1  Protección: 
Si  varios  procesos  comparten la  memoria  principal,  se debe asegurar que ninguno de ellos pueda modificar  posiciones de memoria de otro proceso.
Aunque la escritura de memoria tiene efectos más desastrosos , la lectura de memoria ajena tampoco debe estar permitida, pues cada proceso debe mantener su privacidad. Ya que muchos lenguajes de programación disponen de punteros dinámicos e indexación de vectores o matrices, las comprobaciones en tiempo de compilación no son suficientes y  se requiere que el sistema de gestión de memoria realice chequeos adicionales durante la ejecución.
Debe disponerse de un sistema de permisos de acceso que especifique los derechos que tiene cada proceso en el acceso a zonas de memoria de otros procesos.

1.2. Compartimiento : 

El compartimiento de la memoria parece estar en contradicción con la protección, pero es que a menudo también es necesario que varios procesos puedan compartir y actualizar estructuras de datos comunes, por ejemplo, en un sistema de bases de datos. En otras ocasiones, lo que se requiere es compartir zonas de código, por ejemplo, en rutinas de biblioteca, para no tener en memoria distintas copias de la misma rutina. En este caso, se hace necesaria alguna protección para que un proceso no modifique inadvertidamente el código de las rutinas.

1.3. Reubicación:

La multiprogramación requiere que varios procesos residan simultáneamente en memoria. Lo que no se puede saber antes de llevarlo a memoria es la dirección absoluta en la que se va a cargar el proceso, por lo que no es práctico utilizar direcciones absolutas en el programa.
En su lugar, es preferible realizar direccionamientos relativos para permitir que un programa pueda ser cargado y ejecutado en cualquier parte de la memoria.

1.4. Organización de memoria:

La memoria se debe organizar tanto física como lógicamente.
Debido al coste de la rápida memoria RAM, normalmente se necesita ampliarla con memoria secundaria más barata (y más lenta), utilizando para ello dispositivos tales como discos o cintas magnéticas. Por el contrario, también puede resultar conveniente añadir memoria de acceso más rápido que la RAM principal, como es el caso de la memoria caché, en la que se mantienen los datos de acceso más frecuente. Esta jerarquía física de memorias hace necesario un sistema que controle el flujo de información entre los distintos dispositivos de almacenamiento. Esta tarea la realizaba el programador utilizando overlays, pero consume una gran cantidad de tiempo y, debido a la reubicación dinámica, el programador no siempre sabe la cantidad y lugar de la memoria que se va a necesitar.

Por esto, parece conveniente que sea el gestor de memoria el que se ocupe de esta labor. Aunque la mayoría de las memorias están organizadas como un único  espacio lineal de direcciones secuenciales, que van desde 0 hasta un máximo,  esto no refleja la estructura lógica de los programas, que utilizan estructuras lógicas de instrucciones y datos, tales como módulos, rutinas o procedimientos, matrices, registros, etc. Si una gestión de memoria pudiera proporcionar varios espacios de direcciones, cada estructura lógica podría ser una entidad independiente: un segmento. Esto sería ventajoso por varias razones, pues  los segmentos pueden compilarse y cargarse de forma independiente, teniendo cada uno de ellos sus  propios derechos de acceso (lectura, escritura, ejecución). Un sistema simple de segmentación puede constar de sólo dos segmentos: uno para código (con permiso de ejecución) y otro para datos (con permiso de lectura y escritura). Una segmentación más sofisticada podría utilizar un segmento para cada estructura lógica.

2.  GESTIÓN DE MEMORIA INTERNA  

En los sistemas de gestión de memoria sin intercambio, la idea básica consiste en cargar el programa a ejecutar en algún lugar de la memoria principal,donde permanece hasta que finaliza su ejecución, momento en el que abandona el espacio de memoria utilizado.

2.1. Mono programación

El esquema de memoria más simple consiste en mantener la memoria ocupada con un único proceso. Cuando se carga un programa que se hace cargo de toda la memoria y del control completo de la máquina, se dice que el programa se carga sobre una máquina desnuda es decir, una máquina en la que solamente se ofrece el hardware puro, sin ninguna ayuda software que lo recubra. Las máquinas desnudas se utilizaron de forma general hasta principios de los años 60, y actualmente se suelen utilizar en sistemas empotrados de control.

Más tarde, a las máquinas desnudas se les añadió una especie de sistema operativo muy rudimentario al que se le denominó monitor. Las funciones que ofrecía el monitor eran las estrictamente necesarias para cargar un programa en memoria y controlar su ejecución, todo de forma muy manual y con una completa supervisión del usuario. 

La memoria está ocupada por el sistema operativo, que suele estar en RAM, y por el cargador inicial del sistema operativo (IPL) y los  de dispositivos, que suelen estar en memoria ROM. El resto de la memoria RAM queda disponible como área de usuario. Cuando el sistema está organizado de esta manera (por ejemplo MS-DOS), sólo se ejecuta un proceso a la vez. El usuario teclea un comando en el terminal, y el sistema operativo carga el programa correspondiente de disco a memoria principal y lo ejecuta. Cuando el programa termina, el sistema queda a la espera de que el usuario escriba otro comando, para cargar otro programa en la misma zona de memoria que el anterior.

2.2 Multiprogramación Con Particiones Fijas

Ya que, en general, es deseable que haya varios procesos de usuario residiendo en memoria al mismo tiempo, se hace necesario considerar el problema de cómo asignar memoria disponible a varios de los procesos que están en la cola de espera para ser traídos a memoria principal. Lo más inmediato y simple es dividir la memoria en b particiones (posiblemente de distinto tamaño), de tal forma que en cada partición se mete un proceso, donde permanece hasta que finaliza su ejecución. Una vez terminado el proceso, la partición queda libre para acoger a un nuevo trabajo. Con la llegada de la multiprogramación y este esquema de memoria aparecen algunos problemas y cuestiones que deben solventarse, como la planificación de procesos a largo plazo, la determinación del número y tamaño de las particiones, la ubicación de los programas y la protección de las particiones de memoria.

- Planificación

  • Un esquema posible para la planificación de procesos a largo plazo, o sea, para seleccionar los procesos que van cargarse en memoria para ser ejecutados, puede consistir en que cada una de las particiones tenga una cola asociada, de tal manera que en cada una de ellas se van encolando los trabajos o procesos dependiendo del espacio de memoria requerido. Cuando hay que cargar un trabajo, se le pone en la cola de entrada de la partición más pequeña en la que quepa. Ya que en este esquema las particiones son de tamaño fijo preestablecido, cualquier espacio de una partición no utilizado por el proceso cargado, se desaprovecha. La desventaja de meter en colas los trabajos según su tamaño se hace patente cuando la cola de una partición grande está vacía, pero la cola de una partición pequeña tiene muchos trabajos. Una solución consiste en tener una única cola. Cuando una partición se queda libre, el primer trabajo de la cola que quepa en esa partición, se carga en ella y se ejecuta

  • Ya que no es deseable malgastar una partición grande con un trabajo pequeño, una alternativa puede ser el  recorrer la cola entera y elegir el trabajo más grande que se pueda cargar en la partición que acaba de quedar libre. No obstante, esto supone una discriminación de los trabajos con pocos requisitos de memoria, que no son merecedores de tener una partición grande, mientras que normalmente a los trabajos pequeños se les suele dar el mejor servicio, no el peor.
  • Para solucionarlo, se suele disponer siempre de alguna partición de poco tamaño, para permitir que los pequeños trabajos también se ejecuten sin necesidad de asignarles grandes particiones de memoria. No obstante, debe tenerse en cuenta que un proceso que requiera poca memoria y mucha CPU puede entonces formar una larga cola de espera por su partición.
- Tamaño De Las Particiones

  • El tamaño de cada una de las particiones lo puede establecer el operador en el momento de arranque del sistema o figurar en algún fichero de configuración del sistema. Como se puede ver, el grado de multiprogramación está directamente ligado al número de particiones del sistema. A más particiones, más procesos cargados y, por lo tanto,  mayor aprovechamiento de la CPU. Así, cuanta más memoria se desperdicie, menos procesos se podrán tener en memoria. Para lograr el mayor aprovechamiento de la memoria los procesos deberían cargarse en particiones cuyo tamaño se ajuste lo más posible (por exceso) al del proceso. Por una parte tenemos que si dividimos la memoria del sistema en muchas particiones pequeñas, puede dar lugar a que algunos programas grandes no puedan cargarse en memoria aunque haya suficiente memoria disponible, si ésta no se encuentra adyacente en una única partición, dando lugar, en este caso, a una fragmentación externa de la memoria. Si por el contrario, se dispone de unas pocas particiones grandes, los programas pequeños desaprovecharán la memoria sobrante de la partición que ocupen, lo que da lugar a una fragmentación interna.
          Los tamaños de las particiones suelen establecerse después de un estudio sobre los tamaños 
          habituales de los programas que se ejecutan en cada máquina. 

- Reubicación De Programas

  • Cuando se monta o enlaza un programa compuesto por diferentes módulos, todos ellos se combinan en un único módulo cargable, en el que las referencias a sus objetos locales (rutinas o datos) son direcciones que van desde cero hasta la correspondiente al tamaño del módulo. Así, si el módulo se carga en la dirección cero de memoria principal, se ejecutará correctamente, pero no si se carga en cualquier otra dirección. Según esto, habría que decirle al montador en qué dirección se va a cargar ese programa.  
  •  Una posible solución consiste en modificar las direcciones del programa a medida que se carga en memoria. O sea, que a los programas que se carguen en la partición 1 se les añadirá Base_Partición_1 a todas las direcciones a las que haga referencia, Base_Partición_2 a los que se carguen en la partición 2, etc.; siendo la base de la partición, su dirección de comienzo. Para realizar esto, el montador debe incluir en el módulo cargable una lista con las direcciones relativas del programa en las que hay bytes o palabras cuyo contenido son referencias a memoria, de tal forma que puedan ser reubicadas en la carga. Con esta solución se consiguen programas Estáticamente reubicables (reubicables en tiempo de carga), pero tienen una pega:
  • “No permite que un programa cargado en una partición pueda moverse a otra distinta antes de finalizar su ejecución, lo cual resulta de gran utilidad, como veremos posteriormente.”
  • Este problema se solventa con un poco de ayuda del hardware. Consiste en equipar al procesador con un nuevo registro: el Registro Base



Cuando un proceso es seleccionado para pasar a ejecución, el registro base se carga con la dirección de la partición que contiene al proceso en cuestión. Una vez que el proceso está en ejecución, a cada referencia a memoria se le añade automáticamente el contenido del registro base, generando así la dirección definitiva, sin necesidad de modificar el contenido del módulo ejecutable, ni en la carga ni durante la ejecución. A este sistema en el que ya sí se permite ejecutar programas en cualquier partición de memoria e incluso cambiarlos de partición durante su ejecución, se le conoce como sistema de reubicación dinámica.
Solucionado el asunto de la reubicación, debemos afrontar un último problema, pues el sistema de gestión de memoria que hemos visto hasta ahora no  segura que un programa no pueda construir una instrucción en la que referencie cualquier dirección de memoria y acceda ilegalmente a datos de áreas no autorizadas. Esto se resuelve con un “sistema de protección”.


-Protección: 

El sistema de protección se encarga de evitar el acceso indiscriminado a cualquier área de memoria. A partir del sistema de reubicación dinámica resulta fácil limitar las referencias a memoria que puedan hacerse desde un programa. Para ello añadimos un registro más al procesador: el Registro Lïmite.El registro límite expresa el tamaño del programa en ejecución. Cada dirección virtual (relativa) a la que se hace referencia en el proceso se compara con el valor del registro límite, de tal forma que si tal dirección es menor que el registro límite, quiere decir que hace referencia a una posición dentro del programa, por lo que simplemente hay que añadirle el contenido del registro base para obtener la dirección efectiva (También puede realizarse la comprobación del registro límite paralelamente a la suma del registro base). Si por el contrario, la dirección virtual excede al valor del registro límite, indica que se intenta un acceso a una posición de memoria fuera del área ocupada por el programa, en cuyo caso habrá que generar la correspondiente excepción de  Error de Direccionamiento, para darle el tratamiento pertinente.

El tamaño que ocupa un proceso suele venir indicado en el módulo cargable, y puede guardarse en el BCP de cada proceso. El uso de las particiones fijas es prácticamente nulo hoy día. Como ejemplo de un sistema operativo con esta gestión de memoria tenemos al antiguo OS/MFT, utilizado por los grandes ordenadores de IBM.
-->
1.2.3 Intercambio De Memoria

Consiste en trasladar el código y los datos de un proceso completo de memoria al sistema de almacenamiento secundario, para cargar otro previamente almacenado, no permiten a un proceso utilizar más memoria RAM de la que realmente existe en el sistema. Esta técnica puede ser ineficiente ya que se tiene que hacer el intercambio completo del proceso, aunque éste solo vaya a ejecutar una pequeña porción del código.

Durante el intercambio un proceso puede ser sacado temporalmente de memoria y llevado a un lugar especial del disco y posteriormente vuelto a memoria y continuada su ejecución.

Asignación contigua

La memoria principal normalmente se divide en dos particiones: Sistema operativo residente, normalmente en la parte baja de memoria con los vectores de interrupción. Procesos de usuario en la parte alta.

Asignación de partición simple

Puede utilizarse un esquema de registro de relocalización y límite para proteger un proceso de usuario de otro y de cambios del código y datos del sistema operativo.
El registro de relocalización contiene la dirección física más pequeña; el registro limite contiene el rango de las direcciones lógicas. Cada dirección lógica debe ser menor al registro limite

Asignación de particiones múltiples

Bloques de distintos tamaños están distribuidos en memoria, cuando llega un proceso se le asigna un hueco suficientemente grande para acomodarle.

  • El sistema operativo debe tener información sobre:
  - Particiones asignadas
  - Particiones libres (huecos)
  - Asignación de partición dinámica

  El proceso de compactación es una instancia particular del problema de asignación de memoria dinámica, el cual es el cómo satisfacer una necesidad de tamaño n con una lista de huecos libres. Existen muchas soluciones para el problema. El conjunto de huecos es analizado para determinar cuál hueco es el más indicado para asignarse. 

Las estrategias más comunes para asignar algún hueco de la tabla son:

Primer ajuste
Consiste en asignar el primer hueco con capacidad suficiente. La búsqueda puede iniciar ya sea al inicio o al final del conjunto de huecos o en donde terminó la última búsqueda. La búsqueda termina al encontrar un hueco lo suficientemente grande.

Mejor ajuste
Busca asignar el espacio más pequeño de los espacios con capacidad suficiente. La búsqueda se debe de realizar en toda la tabla, a menos que la tabla esté ordenada por tamaño. Esta estrategia produce el menor desperdicio de memoria posible.

 Peor ajuste

Asigna el hueco más grande. Una vez más, se debe de buscar en toda la tabla de huecos a menos que esté organizada por tamaño. Esta estrategia produce los huecos de sobra más grandes, los cuales pudieran ser de más uso si llegan procesos de tamaño mediano que quepan en ellos. 




1.2.4 Multiprogramación Con Particiones Variables

El tamaño de las particiones varía constantemente a medida que los procesos van y vienen.
Inicialmente toda la memoria de usuario está disponible, organizada como un único y gran bloque de memoria libre, Cuando un proceso llega y necesita memoria, se busca en el conjunto de huecos uno que sea suficientemente grande. Si el hueco es demasiado grande, se parte en dos: uno se asigna al proceso, y el otro se devuelve al conjunto de huecos. Cuando un proceso finaliza, se libera su bloque de memoria, que se pone de vuelta en el conjunto de huecos. Si este hueco resulta estar adyacente a otros huecos (a otros bloques libres), se unen los bloques adyacentes en un único bloque del tamaño total. Ahora hay que comprobar si hay más procesos esperando memoria y si este nuevo bloque liberado y recombinado puede satisfacer las demandas de cualquiera de estos procesos que están esperando.

OS/MVT es uno de los antiguos e importantes sistemas operativos de IBM que utilizaba particiones variables.



1.3 Gestión de bloques de memorias
En general, hay tres métodos utilizados por los sistemas operativos para llevar la cuenta de la memoria utilizada y de los huecos libres:

1.3.1 Mapa de Bits
Con este método de gestión de memoria, ésta se divide en cuyo tamaño puede ir desde unas cuantas palabras a varios Kbytes, cada una de estas unidades de asignación se corresponde con un bit en el mapa de bits de memoria; la primera unidad con el primer bit, la segunda con el segundo, etc., de tal forma que si el bit está a 0 indica que la unidad de asignación correspondiente se encuentra libre, mientras que si está a 1 quiere decir que la unidad está ocupada, o sea, asignada a algún proceso. El tamaño de la unidad de asignación es una cuestión muy importante. Cuanta más pequeña sea la unidad, mayor será el mapa de bits.

No obstante, obsérvese que incluso con una unidad de tan solo 4 bytes, tenemos que 32 bits de memoria requieren solamente 1 bit en el mapa. Si la unidad de asignación es de gran tamaño, habrá pocas unidades, luego el mapa de bits ocupará poco espacio; pero por contra, tenemos que puede empezar a ser significativo el espacio correspondiente al 50% de memoria que por término medio se desperdicia en la   última de las unidades asignadas al proceso. Este método es simple y sencillo de implementar, pero tiene la desventaja de que cuando se buscan ‘n’ unidades consecutivas de memoria para asignar a algún proceso, se debe buscar en el mapa de bits hasta encontrar ‘n’ bits consecutivos a 0.

Aunque esta operación es lenta, los procesadores actuales suelen incluir instrucciones de búsquedas de cadenas de bits, favoreciendo así la utilización  de los  mapas de bits.


1.3.2  Lista de bloques

  • El algoritmo más simple es el primero que sirve. El gestor de memoria recorre la lista hasta encontrar un hueco que sea suficientemente grande para satisfacer la petición. Si el hueco elegido no es exactamente del tamaño  solicitado, se divide en dos partes: una (del tamaño solicitado) se le asigna al proceso que lo solicitó, y la otra (con la memoria sobrante) se deja como un hueco de menor tamaño. 

  • el siguiente que sirva. Con este algoritmo, la lista es circular, es decir, que el último nodo apunta al primero y la cabecera no es siempre la misma, sino que va rotando por la lista, es decir, que el orden de la lista va rotando.Esto hace que los bloques fraccionados no se amontonen en una parte de la lista sino que se distribuyan de manera uniforme. Así, cada vez que se comienza una búsqueda, no habrá que atravesar todos los bloques pequeños, sino solamente algunos, con la consecuente ganancia de tiempo. 
  • el que mejor se adapte que recorre la lista completa para seleccionar el hueco que mejor se adapte, o sea, el menor de los que sirvan, para no fraccionar un bloque grande que pudiera servir para alguna petición posterior. 
  • el que peor se adapte que se selecciona el bloque más grande de la lista y se parte en dos, generando así un nuevo bloque libre que, aunque más pequeño, seguramente tendrá un tamaño significativo, evitando así la generación de huecos pequeños. Sin embargo, la simulación ha demostrado que tampoco ha resultado ser una buena idea.
1.3.3.- Sistemas buddy

La ventaja de este algoritmo sobre otros que también ordenan conforme al tamaño, es que cuando se libera un bloque de tamaño 2k  bytes, el gestor de memoria  para ver si la compactación es posible.

Solamente  tiene que buscar en la lista de huecos de longitud 2. La desventaja es su ineficiencia en el aprovechamiento de la memoria, debido a los redondeos hasta una potencia de 2 en el tamaño de los  bloques asignados, dando lugar, en consecuencia, a una fragmentación interna.



MEMORIA VIRTUAL

Sabemos que para ejecutar las instrucciones de un programa, éstas, al igual que sus operandos, tienen que estar en memoria principal. Esta imposición parece necesaria y razonable,  pero  por  desgracia  limita  el  tamaño  de  un  programa  al espacio de memoria física (RAM).

Sin embargo, el examen de los programas reales nos muestra que en muchos casos no es necesario que el programa entero permanezca siempre en memoria. Por ejemplo:
Los  programas  suelen  tener  código  para  manejar  condiciones  de  error inusuales. Ya que estos errores raramente se producen en la práctica, este código casi nunca se ejecuta.

A veces, las tablas, listas o matrices se declaran con más tamaño del que luego realmente necesitan. Una matriz se puede declarar de 100 por 100 aunque raramente ocupe más de 10 por 10; o un ensamblador puede tener una tabla para albergar a 3000 símbolos, aunque la media de los programas no tengan más de 200.

La memoria virtual es una técnica que permite la ejecución de procesos que pueden no estar completamente en memoria principal.

La habilidad de poder ejecutar un programa que sólo está parcialmente en memoria principal acarrea los siguientes beneficios:

  • El tamaño de un programa no está limitado por la cantidad de memoria física disponible. Los usuarios escriben programas contando con un espacio de direcciones virtuales extremadamente grande.


  • Debido a que cada programa puede necesitar para ejecutarse menos memoria que  la  que  ocupa  su  tamaño  total,  se  pueden  cargar  más  programas  en memoria para ejecutarlos al mismo tiempo, con la consiguiente mejora en el aprovechamiento de la CPU.


  • Ya que de cada programa solamente hay que cargar la parte necesaria en un momento  dado,  a  la  hora  de  cargar  un  proceso  o  expulsarlo  a  disco,  se necesitan menos operaciones de E/S debidas al intercambio, por lo que se consigue una ejecución global más rápida.

Sabemos  que  para  ejecutar  una  instrucción,  ésta  y  sus  operandos  deben encontrarse en memoria principal. 

¿Por qué no en memoria secundaria? Simplemente porque el acceso es mucho más rápido a memoria RAM que a los discos

El  ancho  del  bus  de  direcciones  establece  el  rango  de  direcciones  que  puede generar la CPU (direcciones virtuales). 

Por otra parte tenemos la memoria física, es decir, los transistores que forman bytes o palabras, tal que cada uno de los bytes tiene una dirección (dirección real). 

Para  implementar  los  sistemas  de  memoria  virtual,  normalmente  se  utiliza  la paginación. También  se  puede implementar mediante   segmentación, como lo hace el sistema OS/2 de IBM, pero los algoritmos son bastante más complejos que los de la paginación, pues a diferencia de las páginas, los segmentos son de tamaño variable.







PAGINACION


En la gestión de memoria con intercambio, cuando había que pasar un proceso a ejecución, era necesario traer el proceso entero de disco a memoria principal.

Con memoria virtual hemos dicho que no se trae todo el proceso, sino que cuando se hace referencia a una dirección de memoria virtual cuya correspondiente memoria física reside en disco, se trae el contenido de disco a RAM.

¿Quiere esto decir que la unidad de intercambio de memoria es el byte? Si lo fuera, daría lugar a que continuamente se estuviesen generando operaciones de E/S, lo cual sería poco eficaz. Claramente, parece más conveniente utilizar bloques más grandes, para aprovechar de manera más eficiente cada operación de E/S.



Tablas de páginas

Cada página tiene un número que se utiliza como índice en la tabla de páginas, lo que da por resultado el número del marco correspondiente a esa página virtual. Si el bit presente / ausente es 0, se provoca un señalamiento (trap) hacia el sistema operativo. Si el bit es 1, el número de marco que aparece en la tabla de páginas se copia en los bits de mayor orden del registro de salida, junto con el ajuste (offset) de 12 bits, el cual se copia sin modificaciones de la dirección virtual de entrada. 

Juntos forman una dirección física de 15 bits. El registro de salida se coloca entonces en el bus de la memoria como la dirección en la memoria física.


Estructura de la tabla de paginas

  • Protección: Expresa los permisos de acceso del proceso. En caso de tener permiso para la operación de lectura/escritura que se va a realizar, se consulta el resto de los campos.


  • Bit de Presencia: Indica si la página está presente en memoria principal o no. Si se encuentra en RAM, también tienen sentido los siguientes campos.


  • Marco Ocupado: Si la página se encuentra en memoria principal, este campo expresa el marco que la contiene.


  • Modificada (Bit de ensuciada): Este campo indica si el contenido de la página ha sido modificado desde que se trajo de la memoria secundaria.


  • Referenciada: Este campo booleano se pone a cierto cada vez que se hace referencia a cualquier dirección de la página. Lo utiliza el sistema operativo para ayudar a los algoritmos de sustitución de páginas.



Características de la paginación

  • El espacio de direcciones lógico de un proceso puede ser no contiguo.


  • Se divide la memoria física en bloques de tamaño fijo llamados marcos (frames).


  • Se divide la memoria en bloques de tamaño llamados páginas.


  • Se mantiene información en los marcos libres.


  • Para correr un programa de en páginas de tamaño, se necesitan encontrar n marcos y cargar el programa.


  • Se establece una tabla de páginas para trasladar las direcciones lógicas a físicas.


  • Se produce fragmentación interna.



Ventajas de la paginación

  • Es posible comenzar a ejecutar un programa, cargando solo una parte del mismo en memoria, y el resto se cargara bajo la solicitud.


  • No es necesario que las paginas estén contiguas en memoria, por lo que no se necesitan procesos de compactación cuando existen marcos de páginas libres dispersos en la memoria.


  • Es fácil controlar todas las páginas, ya que tienen el mismo tamaño.


  • El mecanismo de traducción de direcciones (DAT) permite separar los conceptos de espacio de direcciones y espacios de memoria. Todo el mecanismo es transparente al usuario.



Desventajas de la paginación

  • El costo de hardware y software se incrementa, por la nueva información que debe manejarse y el mecanismo de traducción de direcciones necesario. Se consumen muchos más recursos de memoria, tiempo en el CPU para su implantación.


  • Se deben reservar áreas de memoria para las PMT de los procesos. Al no ser fijo el tamaño de estas, se crea un problema semejante al de los programas (cómo asignar un tamaño óptimo sin desperdicio de memoria, u ovearhead del procesador).

SEGMENTACIÓN
Es un esquema de manejo de memoria mediante el cual la estructura del programa refleja su división lógica, llevándose a cabo una agrupación lógica de la información en bloques de tamaño variable denominados segmentos. Cada uno de ellos tienen información lógica del programa: subrutina, arreglo, etc. Luego, cada espacio de direcciones de programa consiste de una colección de segmentos, que generalmente reflejan la división lógica del programa. 

OBJETIVOS: 
  • Modularidad de programas: Cada rutina del programa puede ser un bloque sujeto a cambios y recopilaciones, sin afectar por ello al resto del programa. 
  • Estructuras de datos de largo variable: Ejm. Stack, donde cada estructura tiene su propio tamaño y este puede variar. 
  • Protección: Se pueden proteger los módulos del segmento contra accesos no autorizados. 
  • Compartición: Dos o más procesos pueden ser un mismo segmento, bajo reglas de protección; aunque no sean propietarios de los mismos. 
  • Enlace dinámico entre segmentos: Puede evitarse realizar todo el proceso de enlace antes de comenzar a ejecutar un programa. Los enlaces se establecerán sólo cuando sea necesario.


Ventajas de la segmentación

El esquema de segmentación ofrece las siguientes ventajas: 
  • El programador puede conocer las unidades lógicas de su programa, dándoles un tratamiento particular. 
  • Es posible compilar módulos separados como segmentos el enlace entre los segmentos puede suponer hasta tanto se haga una referencia entre segmentos. 
  • Debido a que es posible separar los módulos, se hace más fácil la modificación de los mismos. Cambios dentro de un módulo no afecta al resto de los módulos. 
  • Es fácil el compartir segmentos. 
  • Es posible que los segmentos crezcan dinámicamente según las necesidades del programa en ejecución. 
  • Existe la posibilidad de definir segmentos que aún no existan. Así, no se asignará memoria, sino a partir del momento que sea necesario hacer usos del segmento. Un ejemplo de esto, serían los arreglos cuya dimensión no se conoce hasta tanto no se comienza a ejecutar el programa. En algunos casos, incluso podría retardar la asignación de memoria hasta el momento en el cuál se referencia el arreglo u otra estructura de datos por primera vez.

SEGMENTACIÓN PAGINADA

Paginación y segmentación son técnicas diferentes, cada una de las cuales busca brindar las ventajas enunciadas anteriormente. 
Para la segmentación se necesita que estén cargadas en memoria áreas de tamaños variables. Si se requiere cargar un segmento en memoria que antes estuvo en ella y fue removido a memoria secundaria, se necesita encontrar una región de la memoria lo suficientemente grande para contenerlo, lo cual no es siempre factible. En cambio recargar una página implica sólo encontrar un marco de página disponible. 
A nivel de paginación, si quiere referenciar en forma cíclica n paginas, estas deberán ser cargadas una a una, generándose varias interrupciones por fallas de páginas. Bajo segmentación, esta página podría conformar un sólo segmento, ocurriendo una sola interrupción por falla de segmento. No obstante, si bajo segmentación se desea acceder un área muy pequeña dentro de un segmento muy grande, este deberá cargarse completamente en memoria, desperdiciándose memoria. Bajo paginación sólo se cargará la página que contiene los ítems referenciados. 
Puede hacerse una combinación de segmentación y paginación para obtener las ventajas de ambas. En lugar de tratar un segmento como una unidad contigua, éste puede dividirse en páginas. Cada segmento puede ser descrito por su propia tabla de páginas. 

Las direcciones tienen tres componentes: (s, p, d), donde la primera indica el número del segmento, la segunda el número de la página dentro del segmento y la tercera el desplazamiento dentro de la página. Se deberán usar varias tablas: 

- SMT (tabla de mapas de segmentos): Una para cada proceso. En cada entrada de la SMT se almacena la información descrita bajo segmentación pura, pero en el campo de dirección se indicara la dirección de la PMT (tabla de mapas de páginas) que describe a las diferentes páginas de cada segmento. 
- PMT (tabla de mapas de páginas): Una por segmento; cada entrada de la PMT describe una página de un segmento, en la forma que se presentó la pagina pura. 
- TBM (tabla de bloques de memoria): Para controlar asignación de páginas por parte del sistema operativo. 
- JT (tabla de Jobs): Que contiene las direcciones de comienzo de cada una de las SMT de los procesos que se ejecutan en memoria. 


Ventajas y Desventajas de la segmentación paginada

Ventajas de la segmentación paginada: 

  • El esquema de segmentación paginada tiene todas las ventajas de la segmentación y la paginación:  
  •  Debido a que los espacios de memorias son segmentados, se garantiza la facilidad de implantar la compartición y enlace. 
  • Como los espacios de memoria son paginados, se simplifican las estrategias de almacenamiento. 
  • Se elimina el problema de la fragmentación externa y la necesidad de compactación.
  
Desventajas de la segmentación paginada: 

  • Los tres componentes de la dirección y el proceso de formación de direcciones hace que se incremente el costo de su implantación. El costo es mayor que en el caso de de segmentación pura o paginación pura. 
  • Se hace necesario mantener un número mayor de tablas en memoria, lo que implica un mayor costo de almacenamiento. 
  • Sigue existiendo el problema de fragmentación interna de todas -o casi todas- las páginas finales de cada uno de los segmentos. Bajo paginación pura se desperdicia sólo la última página asignada, mientras que bajo segmentación paginada el desperdicio puede ocurrir en todos los segmentos asignados.

-->




No hay comentarios:

Publicar un comentario