0% encontró este documento útil (0 votos)
169 vistas28 páginas

Ejecución de Múltiples Programas Sin Una Abstracción de Memoria

El documento describe la evolución de las técnicas de administración de memoria en sistemas operativos, incluyendo la protección de memoria mediante llaves, la abstracción de espacios de direcciones privados para cada proceso a través de registros base y límite, el intercambio y compactación de procesos entre memoria y disco, y la introducción de la memoria virtual mediante paginación para permitir que programas se ejecuten aun cuando sólo existan parcialmente en memoria.

Cargado por

Ciro
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
169 vistas28 páginas

Ejecución de Múltiples Programas Sin Una Abstracción de Memoria

El documento describe la evolución de las técnicas de administración de memoria en sistemas operativos, incluyendo la protección de memoria mediante llaves, la abstracción de espacios de direcciones privados para cada proceso a través de registros base y límite, el intercambio y compactación de procesos entre memoria y disco, y la introducción de la memoria virtual mediante paginación para permitir que programas se ejecuten aun cuando sólo existan parcialmente en memoria.

Cargado por

Ciro
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd

U3

SIN ABSTRACCIÓN DE MEMORIA


Ejecución de múltiples programas sin una abstracción de memoria
La memoria estaba dividida en bloques de 2 KB y a cada uno se le asignaba una
llave de protección de 4 bits
El registro PSW (Program Status Word, Palabra de estado del programa)
también contenía una llave de 4 bits.
El hardware de la 360 controlaba mediante un trap cualquier intento por parte
de un proceso en ejecución de acceder a la memoria con un código de
protección distinto del de la llave del PSW
Como sólo el sistema operativo podía modificar las llaves de protección, los procesos
de usuario fueron controlados para que no interfirieran unos con otros, ni con el
mismo sistema operativo.
El problema central aquí es que los dos programas hacen referencia a la memoria física
absoluta. Eso, definitivamente, no es lo que queremos; deseamos que cada programa
haga referencia a un conjunto privado de direcciones locales para él.

ADMINISTRACIÓN DE MEMORIA
 jerarquía de memoria
o Mb de memoria caché, muy rápida, costosa y volátil
o Gb de memoria principal, de media velocidad, a precio mediano y volátil
o Tb de almacenamiento en disco lento, económico y no volátil
o Almacenamiento removible, como los DVD’s y las memorias USB.

 Administrador de memoria parte del sistema operativo que administra (parte


de) la jerarquía de memoria. Su trabajo es administrar la memoria con
eficiencia: llevar el registro de cuáles partes de la memoria están en uso,
asignar memoria a los procesos cuando la necesiten y desasignarla cuando
terminen.

UNA ABSTRACCIÓN DE MEMORIA: ESPACIOS DE DIRECCIONES


 La noción de un espacio de direcciones
Mejor solución inventar una nueva abstracción para la memoria: el espacio de
direcciones es el conjunto de direcciones que puede utilizar un proceso para
direccionar la memoria.
 Cada proceso tiene su propio espacio de direcciones,
independiente de los que pertenecen a otros procesos

 Registros base y límite


La solución sencilla utiliza la reubicación dinámica. Lo que hace es asociar el espacio de
direcciones de cada proceso sobre una parte distinta de la memoria física, de una
manera simple.
Equipa a la CPU con dos registros especiales: BASE y LIMITE
 Cuando se utilizan estos registros, los programas se cargan en ubicaciones
consecutivas de memoria en donde haya espacio y sin reubicación durante la
carga.
 Cuando se ejecuta un proceso, el registro base se carga con la dirección física
donde empieza el programa en memoria y el registro límite se carga con la
longitud del programa.
El uso de registros base y límite es una manera fácil de proporcionar a cada proceso su
propio espacio de direcciones privado, ya que a cada dirección de memoria que se
genera en forma automática se le suma el contenido del registro base antes de
enviarla a memoria.
Una desventaja de la reubicación usando los registros base y límite es la necesidad de
realizar una suma y una comparación en cada referencia a memoria.

 Intercambio
Un sistema puede ejecutar de 40 a 60 procesos cuando inicia el SO, la memoria física
puede no ser suficiente para ellos.
 El intercambio, consiste en llevar cada proceso completo a memoria, ejecutarlo
durante cierto tiempo y después regresarlo al disco.
Los procesos inactivos mayormente son almacenados en disco, de tal manera que no
ocupan memoria cuando no se están ejecutando.
 La otra estrategia, conocida como memoria virtual, permite que los programas
se ejecuten incluso cuando sólo se encuentran en forma parcial en la memoria.
Compactación de memoria: Cuando el intercambio crea varios huecos en la memoria,
es posible combinarlos todos en uno grande desplazando los procesos lo más hacia
abajo que sea posible.
 No se realiza debido a que requiere mucho tiempo CPU. Por ej, en una máquina
con 1 GB que pueda copiar 4 bytes en 20 nseg, se requerirían
aproximadamente 5 segundos para compactar 1GB.

 ¿Cuánta memoria se asigna a los programas?


 Si los procesos se crean con un tamaño, entonces el sistema operativo
asigna exactamente lo necesario.
 Los procesos pueden crecer, por ej mediante la asignación dinámica de
memoria proveniente de un heap.
Si hay un hueco adyacente al proceso, puede asignarse y se permite al proceso
crecer en el hueco; si el proceso está adyacente a otro proceso: el proceso en
crecimiento:
- Tendrá que moverse a un hueco en memoria suficiente
- Intercambiar uno o más procesos fuera de la memoria para crear un
hueco con el tamaño suficiente
- Eliminarse

 Administración de memoria libre


Cuando la memoria se asigna en forma dinámica, el sistema operativo debe
administrarla
 Administración de memoria con mapas de bits
Con un mapa de bits, la memoria se divide en unidades de asignación tan pequeñas
como unas cuantas palabras y tan grandes como varios kilobytes. Para cada unidad de
asignación hay un bit correspondiente en el mapa de bits, que es 0 si la unidad está
libre y 1 si está ocupada (o viceversa).
Entre más pequeña sea la unidad de asignación, mayor será el mapa de bits.
 Administración de memoria con listas ligadas
Otra manera de llevar el registro de la memoria es mantener una lista ligada de
segmentos de memoria asignados y libres, en donde un segmento contiene un proceso
o es un hueco vacío entre dos procesos.

Cuando los procesos y huecos se mantienen en una lista ordenada por dirección, se
pueden utilizar varios algoritmos para asignar memoria a un proceso creado (o a un
proceso existente que se intercambie del disco).
 Primer ajuste: el admin de mem explora la lista de segmentos hasta encontrar
un hueco que sea lo bastante grande. Después el hueco se divide en dos partes,
una para el proceso y otra para la memoria sin utilizar, excepto en el
estadísticamente improbable caso de un ajuste exacto. (Rápido)

 Siguiente ajuste: similar al primer ajuste, lleva un registro de dónde se


encuentra cada vez que descubre un hueco adecuado. La siguiente vez que es
llamado para buscar un hueco, empieza a buscar en la lista desde el lugar en el
que se quedó la última vez. (Menos rendimiento)

 Mejor ajuste: busca en toda la lista y toma el hueco más pequeño que sea
adecuado. Trata de buscar un hueco que esté cerca del tamaño actual
necesario, que coincida mejor con la solicitud y los huecos disponibles. (Más
utilizado, pero más lento)

 Peor ajuste: Para resolver el problema de dividir las coincidencias casi exactas
en un proceso, se toma siempre el hueco más grande disponible, de manera
que el nuevo hueco sea lo bastante grande como para ser útil. (Espacio
desperdicio, puede ser útil)

 Ajuste rápido: mantiene listas separadas para algunos de los tamaños más
comunes solicitados. Misma desventaja los esquemas que se ordenan por el
tamaño del hueco: cuando un proceso termina o es intercambiado, buscan en
sus vecinos para ver si es posible una fusión es un proceso costoso. Si no se
realiza la fusión, la memoria se fragmentará rápidamente en un gran número
de pequeños huecos en los que no cabrá ningún proceso.
MEMORIA VIRTUAL

Administra el agrandamiento del software (bloatware), software que ve su utilidad


reducida debido a uso excesivo de espacio en disco y memoria.
Problema: programas cada vez más grandes.
Solución: sobrepuestos (overlays)
 Consiste en separar el programa en partes que entran en la memoria, y serán
ejecutadas por un admin de overlays en orden. (lento, aburrido, errores)

MEMORIA VIRTUAL (Mejor solución, Fotheringham, 1961)

 Cada programa tiene su propio espacio de direcciones, el cual se divide en


trozos llamados páginas.
 Cada página es un rango contiguo de direcciones mapeado en una dir. física.
Pero esto último no es obligatorio.
 El SO mapea las direcciones de las paginas y dir. físicas sobre la marcha, cuando
una pág. no está en la memoria, SO se encarga de traerla.

Cuando el programa hace ref. a una parte de dir. que está en la RAM se asocia al
instante sino se produce un fallo de página.

PAGINACIÓN

Los programas hacen referencia a un conjunto de direcciones de memoria. Estas


direcciones generadas por el programa se conocen como direcciones virtuales y
forman el espacio de direcciones virtuales.

 En las computadoras sin memoria virtual, la dirección física se coloca


directamente en el bus de memoria y hace que se lea o escriba la palabra de
memoria física con la misma dirección.

Cuando se utiliza memoria virtual, las direcciones virtuales no van directamente al bus
de memoria. En vez de ello, van a una MMU unidad de admin de memoria, que asocia las
direcciones virtuales a las direcciones de memoria físicas.
En el hardware real, un bit de presente/ausente lleva el registro de cuáles páginas
están físicamente presentes en la memoria.
En cualquier computadora, los programas hacen referencia a un conjunto
de direcciones de memoria.
Estas direcciones generadas por el programa se conocen como direcciones virtuales y
forman
el espacio de direcciones virtuales. En las computadoras sin memoria virtual, la
dirección física
se coloca directamente en el bus de memoria
Cuando se utiliza memoria virtual, las direcciones virtuales no van directamente
al bus de memoria. En vez de ello, van a una MMU (Memory Managemente Unit,)
Unidad de administración de memoria) que asocia las direcciones virtuales a las
direcciones de memoria físicas.

El espacio de direcciones virtuales se divide en unidades de tamaño fijo llamadas


páginas.

Las unidades correspondientes en la memoria física se llaman marcos de página

TABLAS DE PÁGINAS
La asociación de direcciones virtuales a direcciones físicas se puede resumir de la
siguiente manera:

La dirección virtual se divide en un número de página virtual (bits de mayor


orden) y en un desplazamiento (bits de menor orden).
Es posible una división con 3, 5 u otro número de bits para la página. Las
distintas divisiones implican diferentes tamaños de página.
El número de página virtual se utiliza como índice en la tabla de pág para
buscar la entrada para esa página virtual.
En la entrada en la tabla de pág, se encuentra el número de marco de página (si
lo hay). Este se adjunta al extremo de mayor orden del desplazamiento,
reemplazando el número de página virtual, para formar una dirección física que
se pueda enviar a la memoria.
el propósito de la tabla de páginas es asociar páginas virtuales a los marcos de
página.

Tabla de páginas es una función donde el número de página virtual es un argumento y


el número de marco físico es un resultado. Utilizando el resultado de esta función, el
campo de la página virtual en una dirección virtual se puede reemplazar por un campo
de marco de página, formando así una dirección de memoria física.
Estructura de una entrada en la tabla de páginas

El campo más importante es el número de marco de página. Después de todo, el


objetivo de la asociación de páginas es mostrar este valor.

 Bit de protección: q tipo de acceso es permitido


 Bit de modificada: cuando una pág. es escrita, está sucia
 Bit de referencia: sirve para facilitar la tarea del SO de desalojar q no están ref.
 Bit de desactivación: inconsistencia de datos

Vale
----------------------
Aceleración de la paginación
En los sistemas de paginación debemos tener en cuenta:
1. La asociación de una dirección virtual a una dirección física debe ser rápida.
2. Si el espacio de direcciones virtuales es grande, la tabla de páginas será
grande.
● Mantener la tabla de páginas en un registro
○ No se necesitan más accesos a memoria durante el proceso de ejecución
○ Pero es extremadamente costoso, Ya que es una sola tabla de pagina enorme
para todos los procesos.

● Mantener la tabla de páginas en memoria


○ Cada proceso tiene su propia tabla de páginas.
○ La tabla de páginas se mantiene en memoria.
TLB (Búferes de traducción adelantada) - resuelve item 1
Tmb MEMORIA ASOCIATIVA: es un pequeño dispositivo de hardware para asociar
direcciones virtuales a direcciones físicas sin pasar por la tabla de páginas.
Se encuentra dentro de la MMU.
Contiene información acerca de una página, incluyendo el número de página
virtual, un bit que se establece cuando se modifica la página, el código de
protección (permisos de lectura/escritura/ejecución) y el marco de página físico
en el que se encuentra la página.
Este acelera el proceso ya que, si la memoria física necesita buscar algo en la memoria
virtual, este no se va a buscarlas en la tabla de P sino que ya tiene guardadas las
páginas más usadas. Si no llega a tener alguna página  se genera un FALLO. Y la MMU
busca esta página en la tabla de P, saca una página del TBL y mete esta nueva página.
Para saber que paginas poner en el TBL se hace un chequeo antes de que empiece el
proceso para saber cuáles son las páginas más probables a usar.
El sistema operativo solo actuaba en el momento en el que una página no estaba en
memoria virtual y tenía que ir al disco-> TRAP.
En la actualidad la que maneja el FALLO ya no es más la MMU (hardware), sino que lo
hace el SO. Hace exactamente lo mismo que hacia la MMU. Una ventaja de esto es que
la MMU ahora puede ser mucho más simple.
Cuando se utiliza administracion de TBL por software se distinguen los fallos de la sig
manera:
- FALLO SUAVE: la página no está en el TBL y la busca en la tabla de páginas.
- FALLO DURO: (seria como el TRAP q vimos antes) la página no está en la tabla
ni en el TBL entonces la busca en el disco.

Tablas de páginas para memorias extensas para resolver - item 2


Tablas de páginas multinivel
Aunque el espacio de direcciones contiene más de un millón de páginas, en realidad
sólo cuatro tablas de páginas son requeridas: la tabla de nivel superior y las tablas de
segundo nivel de 0 a 4Mb (para el texto del programa), de 4Mb a 8Mb (para los datos)
y los 4M superiores para la pila. Los bits de presente/ausente en 1024 entradas de la
tabla de páginas de nivel superior están en 0 y obligan a que se produzca un fallo de
página si se tratan de utilizar alguna vez.
En caso de que esto ocurra, el sistema operativo observará que el proceso está
tratando de referenciar memoria que no debe y tomará la acción apropiada, como
enviar una señal o eliminarlo. En este ejemplo hemos elegido números redondos para
los diversos tamaños y que TP1 sea igual a TP2, pero en la práctica también es posible
elegir otros valores.

Tablas de páginas invertidas


Los espacios de direcciones virtuales son más grades pasan de 32 bits a 64 bits se
crean estas.
En este diseño hay una entrada por cada marco de página en la memoria real, en vez
de tener una entrada por página de espacio de direcciones virtuales.
La desventaja: la traducción de dirección virtual a dirección física se hace mucho más
difícil. Cuando el proceso n hace referencia a la página virtual p, el hardware ya no
puede buscar la página física usando p como índice en la tabla de páginas. En vez de
ello, debe buscar una entrada (n, p) en toda la tabla de páginas invertida. Lo que es
peor: esta búsqueda se debe realizar en cada referencia a memoria, no sólo en los
fallos de página. Para ello utiliza el TBL
Sin embargo, en un fallo de TLB la tabla de páginas invertida tiene que buscarse
mediante software. Una manera factible de realizar esta búsqueda es tener una tabla
de hash arreglada según el hash de la dirección virtual.
Todas las páginas virtuales que se encuentren en memoria y tengan el mismo valor de
hash se encadenan en conjunto
ALGORITMOS DE REEMPLAZO DE PÁGINAS
¿cuál página elimino de la tabla de páginas en memoria?
*ÓPTIMO
Cada página se puede etiquetar con el número de instrucciones que se ejecutarán
antes de que se haga referencia por primera vez a esa página. Establece que la página
con la etiqueta más alta debe eliminarse. Si una página no se va a utilizar durante 8
millones de instrucciones y otra no se va a utilizar durante 6 millones de instrucciones
entonces elimina la mas alta ósea 8. Desaloja la página a la que se hará referencia en el
futuro más lejano. Por desgracia, no hay forma de determinar cuál página es, por lo
que en la práctica no se puede utilizar este algoritmo. Sin embargo, es útil como punto
de comparación para los demás algoritmos.
*NRU
El algoritmo NRU divide las páginas en cuatro clases dependiendo del estado de los
bits R y M. Se selecciona una página aleatoria de la clase con menor numeración. Este
algoritmo es fácil de implementar, pero muy burdo.
Clase 0: no ha sido referenciada, no ha sido modificada.
Clase 1: no ha sido referenciada, ha sido modificada.
Clase 2: ha sido referenciada, no ha sido modificada.
Clase 3: ha sido referenciada, ha sido modificada
*FIFO
FIFO lleva la cuenta del orden en el que se cargaron las páginas en memoria al
mantenerlas en una lista enlazada. Eliminar la página más antigua se vuelve entonces
un proceso trivial, pero como esa página podría estar todavía en uso, FIFO es una mala
opción. Es decir ¨primera en entrar,primera en salir¨ por ej las heladeras con gaseosa
el que compra saca la de adelnate y el que repone las mete por dentras.
*SEGUNDA OPORTUNIDAD FIFO
El algoritmo de segunda oportunidad es una modificación de FIFO que comprueba si
hay una página en uso antes de eliminarla. Si lo está, ósea R =1  la página VUELVE A
LA COLA. Esta modificación mejora de manera considerable el rendimiento.

*RELOJ
El algoritmo de reloj es simplemente una implementación distinta del algoritmo de
segunda oportunidad. Tiene las mismas propiedades de rendimiento, pero toma un
poco menos de tiempo para ejecutar el algoritmo.

*LRU: hay que descartar la página que no se haya utilizado durante la mayor longitud
de tiempo , es necesario mantener una lista enlazada de todas las páginas en memoria,
con la página de uso más reciente en la parte frontal y la de uso menos reciente en la
parte final. La dificultad es que la lista debe actualizarse en cada referencia a
[Link] algoritmo se aproxima al optimo pero asi no es posible implementarlo.
Primera manera de implementar LRU: con un contador de 64 bits, llamado C, el cual
se incrementa de manera automática después de cada instrucción. Además, cada
entrada en la tabla de páginas debe tener también un campo lo bastante grande como
para poder guardar el contador. Después de cada referencia a memoria, el valor actual
de C se almacena en la entrada en la tabla de páginas para la página que se acaba de
referenciar. Cuando ocurre un fallo de página, el sistema operativo examina todos los
contadores en la tabla de páginas para encontrar el menor.
Segunda manera:

Cuenta la cantidad de veces que es usada cada pagina, la pag menos llamada se
eliminara.
Para mostrar que pag fue llamada 1 en la fila y o en la columna.

*ENVEJECIMIENTO
A diferencia de LRU este utiliza un contador de 8 bits(es finito), y no produce el error q
tiene LRU q al ser infinito puede pensar que una pagina que ha sido llamada muchas
veces pero hace mucho es mas importante que una q fue llamada menos pero hace
poco tiempo.
Tiene un reloj que en cada pulso evalua a R si es 0  contador 0 si es R=1 entonces
contador 1
*CONJUNTO DE TRABAJO: junta a todas las paginas que va a necesitar en un
[Link] cuando empieze a ejecutarse ya casi no exista la posibilidad de fallo de
pagina.
-paginación bajo demanda, debido a que las páginas se cargan sólo según la demanda,
no por adelantado.
-localidad de referencia :durante cualquier fase de ejecución el proceso hace
referencia sólo a una fracción relativamente pequeña de sus páginas.
Se dice que un programa que produce fallos de página cada pocas instrucciones está
sobrepaginando
El proceso producirá fallos de página sólo hasta que se haya cargado su conjunto de
trabajo. El problema es que tener 20, 100 o incluso 1000 fallos de página cada vez que
se carga un proceso es algo lento.
Al eliminar un proceso en memoria se eliminaría el conjunto de paginas q este utiliza
y si vueve a ser llamado debería volver a producir muchos fallos para creae su conjunto
de trabajo. Para que esto no ocurra existe la prepaginación consiste en cargar estas
páginas antes de reanudar el proceso.
-cuando ocurra un fallo de página, hay que buscar una página que no se encuentre en
el conjunto de trabajo y desalojarla.
-Se utiliza el tiempo también para saber cuales paginas se usaron utlimas y este es el
mas eficiente, por lo q este método opta por usarlo aparte de R. La cantidad de tiempo
de la CPU que ha utilizado en realidad un proceso desde que empezó se conoce
comúnmente como su tiempo virtual actual.
El algoritmo del conjunto de trabajo ofrece un rendimiento razonable, pero es un
poco costoso de implementar.

*WSCLOCK
WSClock es una variante que no sólo da un buen rendimiento, sino que también es
eficiente al implementar.
Utiliza el reloj y el conjunto de trabajo. Pone en una lista circular con todas las paginas
con su marco de paginas y en cada pulso se fija se la lista esta limpia =0 la elimina, sino
si esta R=1 por ejemplo: pagina 6 entonces coloca esta en 0 y planifica su escritura en
el disco por si llega a ser la pagina q se eliminara. La manesilla sigue corriendo y si
vuelve a empezar sin haber podido eliminar ninguna , cuando se encuentre con pag 6
la eliminara y la CPU no perdera tiempo en ir al disco ya que hizo este proceso en la
vuelta anterior.
Resumen de algoritmos
Continuación U3
CUESTIONES DE DISEÑO PARA LOS SISTEMAS
DE PAGINACIÓN
Políticas de asignación local contra las de asignación global
los algoritmos globales funcionan mejor, en especial cuando el tamaño del conjunto
de trabajo puede variar durante el tiempo de vida de un proceso.

- Si se utiliza un algoritmo local y el conjunto de trabajo crece, se producirá una


sobre paginación, aun cuando haya muchos marcos de página libres.

- Si el conjunto de trabajo se reduce, los algoritmos locales desperdician


memoria.

Una manera de administrar la asignación es utilizando el algoritmo


PFF (Page Fault Frequency, Frecuencia de fallo de páginas).

Este algoritmo indica cuándo se debe incrementar o decrementar la asignación de


páginas a un proceso, pero no dice nada acerca de cuál página se debe sustituir en un
fallo. Sólo controla el tamaño del conjunto de asignación.

Control de carga (¿Cómo evitar la sobrepaginación?)

Una buena forma de reducir el número de procesos que compiten por la memoria es
intercambiar algunos de ellos enviándolos al disco y liberar todas las páginas que ellos
mantienen.

Si el sobrepaginado se detiene, el sistema puede operar de esta forma por


un tiempo. Si no se detiene hay que intercambiar otro proceso y así en lo sucesivo
hasta que se detenga el sobrepaginado.
Hay que tener en cuenta el costo de copiar datos al disco, el SO completo puede
volverse extremadamente lento durante este proceso.

Tamaño de Página
Para determinar el mejor tamaño de página se requiere balancear varios factores
competitivos.
Un segmento de texto, datos o pila elegido al azar no llenará un número integral de
páginas. En promedio, la mitad de la página final estará vacía.

El espacio adicional en esa página se desperdicia. A este desperdicio se le conoce como


fragmentación interna.

- Con n segmentos en memoria y un tamaño de página de p bytes, se


desperdiciarán np/2 bytes en fragmentación interna

Las transferencias hacia y desde el disco son por lo general de una página a la vez, y la
mayor parte del tiempo se debe al retraso de búsqueda y al retraso rotacional, por lo
que para transferir una página pequeña se requiere casi el mismo tiempo que para
transferir una página grande.

- Fórmula

Digamos que el tamaño promedio de un proceso es de s bytes y que el tamaño de


página es de p bytes. Además, supone que cada entrada de página requiere e bytes.

El número aproximado de páginas necesarias por proceso es entonces s/p, ocupando


se/p bytes de espacio en la tabla de páginas. La memoria desperdiciada en la última
página del proceso debido a la fragmentación interna es p/2.

Fórmula que proporcione el tamaño de página óptimo

Espacios separados de instrucciones y de datos

En una computadora con este diseño, ambos espacios de direcciones se pueden paginar de manera
independiente. Cada uno tiene su propia tabla de páginas, con su propia asignación de
páginas virtuales a marcos de páginas físicas. Cuando el hardware desea obtener una
instrucción, sabe que debe utilizar el espacio I y la tabla de páginas de este espacio.

Aparte de esta distinción, tener espacios I y D separados no introduce ninguna


complicación especial y sí duplica el espacio de direcciones disponible.
Páginas compartidas
En un sistema de multiprogramación grande, es común que varios usuarios ejecuten el
mismo programa a la vez. Es más eficiente compartir las páginas para evitar tener dos
copias de la misma página en memoria al mismo tiempo.

Un problema es que no todas las páginas se


pueden compartir. Sólo pueden compartirse
las páginas que son de sólo lectura como el
texto del programa, pero las páginas de datos
no.

En una implementación que soporta la


compartición de esta forma, las tablas de
páginas son estructuras de datos
independientes de la tabla de procesos.

Cada proceso tiene dos apuntadores en su


tabla de procesos: uno para la tabla de
páginas del espacio I y otro para la tabla de
páginas del espacio D.

PROBLEMA
Sin embargo, puede producirse un error al intentar compartir si A y B están ejecutando
el editor y comparten sus pág., si A decide desalojarlas, B fallará al traerlas de vuelta.
Buscar en todas las tablas de pág. para ver si es compartida sería muy caro, por lo q se
necesita una estructura de datos especial para llevar la cuenta de pág. compartidas.

Bibliotecas compartidas

una técnica común es utilizar bibliotecas compartidas (que se conocen como DLLs o
Bibliotecas de enlaces dinámicos en Windows). Para aclarar la idea de una biblioteca
compartida, primero considere el enlazamiento tradicional. Cuando un programa se
enlaza, se nombra uno o más archivos de código objeto y posiblemente algunas
bibliotecas en el comando para el enlazador.
Archivos asociados
Las bibliotecas compartidas son realmente un caso de una herramienta más general,
conocida como archivos asociados a memoria. La idea aquí es que un proceso puede
emitir una llamada al sistema para asociar un archivo a una porción de su espacio de
direcciones virtuales.

En la mayor parte de las implementaciones no se traen páginas al momento de la


asociación, sino que a medida que se usan las páginas, se paginan bajo demanda una a
la vez, usando el archivo de disco como el almacén de respaldo. Cuando el proceso
termina o desasocia en forma explícita el archivo, todas las páginas modificadas se
escriben de vuelta en el archivo.

Política de limpieza
La paginación funciona mejor cuando hay muchos marcos de página libres que se
pueden reclamar al momento en que ocurran fallos de página. Si cada marco de página
está lleno y además modificado, antes de que se pueda traer una nueva página se
debe escribir una página anterior en el disco.

Para asegurar una provisión abundante de marcos de página libres, muchos sistemas
de paginación tienen un proceso en segundo plano conocido como demonio de
paginación, que está inactivo la mayor parte del tiempo pero se despierta en forma
periódica para inspeccionar el estado de la memoria.

Si hay muy pocos marcos de página libres, el demonio de paginación empieza a


seleccionar páginas para desalojarlas mediante cierto algoritmo de reemplazo de
páginas.
CUESTIONES DE IMPLEMENTACIÓN
Hay cuatro ocasiones en las que el sistema operativo tiene que realizar trabajo
relacionado con la paginación:

- Al crear un proceso
- Al ejecutar un proceso
- Al ocurrir un fallo de página
- Al terminar un proceso.

Manejo de fallos de página


1. El hardware hace un trap al kernel, guardando el contador de programa en
la pila.

2. Se inicia una rutina en código ensamblador para guardar los registros


generales y demás información volátil.

3. El sistema operativo descubre que ha ocurrido un fallo de página y trata de


descubrir cuál página virtual se necesita.

4. Una vez que se conoce la dirección virtual que produjo el fallo, el sistema
comprueba si esta dirección es válida y si la protección es consistente con el
acceso.

5. Si el marco de página seleccionado está sucio, la página se planifica para


transferirla al disco y se realiza una conmutación de contexto.

6. Tan pronto como el marco de página esté limpio (ya sea de inmediato, o
después de escribirlo en el disco), el sistema operativo busca la dirección de
disco en donde se encuentra la página necesaria, y planifica una operación
de disco para llevarla a memoria.

7. Cuando la interrupción de disco indica que la página ha llegado, las tablas


de páginas se actualizan para reflejar su posición y el marco se marca como
en estado normal.

8. La instrucción fallida se respalda al estado en que tenía cuando empezó, y el


contador de programa se restablece para apuntar a esa instrucción.

9. El proceso fallido se planifica y el sistema operativo regresa a la rutina (en


lenguaje ensamblador) que lo llamó.

10. Esta rutina recarga los registros y demás información de estado, regresando
al espacio de usuario para continuar la ejecución, como si no hubiera
ocurrido el fallo.
Respaldo de instrucción
Cuando un programa hace referencia a una página que no está en memoria, la
instrucción que produjo el fallo se detiene parcialmente y ocurre un trap al sistema
operativo.

Una vez que el sistema operativo obtiene la página necesaria, debe reiniciar la
instrucción que produjo el trap. Es más fácil decir esto que hacerlo.

Por ejemplo, la instrucción

MOV.L #6(A1),2(A0)

es de 6 bytes (vea la figura 3-28). Para poder reiniciar la instrucción, el sistema


operativo debe determinar en dónde se encuentra el primer byte de la instrucción. El
valor del contador de programa al momento en que ocurre el trap depende de cuál fue
el operando que falló y cómo se ha implementado el microcódigo de la CPU.

Bloqueo de páginas en memoria


Si el algoritmo de paginación es global, hay una pequeña probabilidad (distinta de
cero) de que la página que contiene el búfer de E/S sea seleccionada para eliminarla de
la memoria.

Si un dispositivo de E/S se encuentra en el proceso de realizar una transferencia por


DMA a esa página, al eliminarla parte de los datos se escribirán en el búfer al que
pertenecen y parte sobre la página que se acaba de cargar.

Una solución a este problema es bloquear las páginas involucradas en operaciones de


E/S en memoria, de manera que no se eliminen. Bloquear una página se conoce a
menudo como fijada (pinning) en la memoria.

Otra solución es enviar todas las operaciones de E/S a búferes del kernel y después
copiar los datos a las páginas de usuario.

Almacén de respaldo
El algoritmo más simple para asignar espacio de página en el disco es tener una
partición de intercambio especial en el disco o aún mejor es tenerla en un disco
separado del sistema operativo (para balancear la carga de E/S).
- Esta partición no tiene un sistema de archivos normal, lo cual elimina la sobrecarga de
convertir desplazamientos en archivos a direcciones de bloque.

- Antes de que un proceso pueda empezar se debe inicializar el área de intercambio.

- Una forma de hacerlo es copiar toda la imagen del proceso al área de intercambio, de
manera que se pueda traer y colocar en la memoria según sea necesario.

- La otra es cargar todo el proceso en memoria y dejar que se pagine hacia fuera según
sea necesario

Separación de política y mecanismo


Aquí, el sistema de administración de memoria se divide en dos partes:

1. Un manejador de la MMU de bajo nivel.


2. Un manejador de fallos de página que forma parte del kernel.
3. Un paginador externo que se ejecuta en espacio de usuario.
SEGMENTACIÓN
un compilador tiene muchas tablas que se generan a medida que
procede la compilación, las cuales posiblemente incluyen:
1. El texto del código fuente que se guarda para el listado impreso (en sistemas
de procesamiento
por lotes).
2. La tabla de símbolos, que contiene los nombres y atributos de las variables.
3. La tabla que contiene todas las constantes enteras y de punto flotante
utilizadas.
4. El árbol de análisis sintáctico, que contiene el análisis sintáctico del
programa.
5. La pila utilizada para las llamadas a procedimientos dentro del compilador.

Cada una de las primeras cuatro tablas crece en forma continua a medida que procede
la compilación. La última crece y se reduce de maneras impredecibles durante la
compilación.

En una memoria
unidimensional, a estas
cinco tablas se les tendría
que asignar trozos
contiguos de espacio de
direcciones virtuales.

La figura 3-32 ilustra el uso


de una memoria
segmentada para las tablas
del compilador que vimos
antes. Aquí se muestran
cinco segmentos
independientes.
Implementación de segmentación pura
La implementación de segmentación difiere de la paginación de una manera esencial:
las páginas tienen un tamaño fijo y los segmentos no.

Una vez que el sistema haya estado en ejecución por un tiempo, la memoria se dividirá
en un número de trozos, de los cuales algunos contendrán segmentos y otros huecos.
Este fenómeno, llamado efecto de tablero de ajedrez o fragmentación externa,
desperdicia memoria en los huecos.

Segmentación con paginación: Intel Pentium


El Pentium tiene 16K segmentos independientes, cada uno de los cuales contiene
hasta un mil millones de palabras de 32 bits.

El corazón de la memoria virtual del Pentium consiste en dos tablas, llamadas LDT
(Local Descriptor Table, Tabla de descriptores locales) y GDT (Global Descriptor Table,
Tabla de descriptores globales).

Cada programa tiene su propia LDT, pero hay una sola GDT compartida por todos los
programas en la computadora. La LDT describe los segmentos locales para cada
programa, incluyendo su código, datos, pila, etcétera, mientras que la GDT describe los
segmentos del sistema, incluyendo el sistema operativo en sí.

Para acceder a un segmento, un programa del Pentium primero carga un selector para
ese segmento en uno de los seis registros de segmento de la máquina. Durante la
ejecución, el registro CS contiene el selector para el segmento de código y el registro
DS contiene el selector para el segmento de datos. Los demás registros de segmento
son menos importantes. Cada selector es un número
de 16 bits:

Después, el hardware utiliza el campo Límite para comprobar si el desplazamiento está


más allá del final del segmento, en cuyo caso también se produce un trap. Lógicamente
debería haber un campo de 32 bits en el descriptor para proporcionar el tamaño del
segmento, pero sólo hay 20 bits disponibles, por lo que se utiliza un esquema distinto.

Suponiendo que el segmento está en memoria y que el desplazamiento está en el


rango, el Pentium suma el campo Base de 32 bits en el descriptor al desplazamiento
para formar lo que se conoce como una dirección lineal.
Cada programa en ejecución tiene un directorio de páginas que consiste de 1024
entradas de 32 bits. Se encuentra en una dirección a la que apunta un registro global.
Cada entrada en este directorio apunta a una tabla de páginas que también contiene
1024 entradas de 32 bits.

Las entradas en la tabla de páginas apuntan a marcos de página.

Mientras que un programa se restrinja a sí mismo a utilizar segmentos en su propio


nivel, todo funcionará bien. Se permiten los intentos de acceder a los datos en un nivel
más alto, pero los de acceder a los datos en un nivel inferior son ilegales y producen
traps. Los intentos de llamar procedimientos en un nivel distinto (mayor o menor) se
permiten, pero de una manera controlada cuidadosamente.

Para realizar una llamada entre niveles, la


instrucción CALL debe contener un selector
en vez de una dirección. Este selector designa
a un descriptor llamado compuerta de
llamada, el cual proporciona la dirección del
procedimiento al que se va a llamar. Por
ende, no es posible saltar en medio de un
segmento de código arbitrario en un nivel
distinto. Sólo se pueden utilizar puntos de
entrada oficiales. Los conceptos de los niveles
de protección y las compuertas de llamada se
utilizaron por primera vez en MULTICS, en
donde se denominaron anillos de protección.
Anillos de protección

● En el nivel 0 encontramos el kernel del sistema operativo, que se encarga de


la E/S, la administración de memoria y otras cuestiones críticas.

● En el nivel 1 está presente el manejador de llamadas al sistema. Los


programas de usuario pueden llamar procedimientos aquí para llevar a cabo las
llamadas al sistema, pero sólo se puede llamar a una lista de procedimientos
específicos y protegidos.

● El nivel 2 contiene procedimientos de biblioteca, posiblemente compartida


entre muchos programas en ejecución. Los programas de usuario pueden llamar a
estos procedimientos y leer sus datos, pero no pueden modificarlos.

● Por último, los programas de usuario se ejecutan en nivel 3, que tiene la


menor protección.

Casos de estudio: llamadas al sistema en Linux relacionadas con


la asignación y liberación de memoria dinámica
★ La función malloc sirve para solicitar un bloque de memoria del tamaño
suministrado como parámetro. Devuelve un puntero a la zona de memoria concedida:
void* malloc ( unsigned numero_de_bytes );

★ Función free: Cuando una zona de memoria reservada con malloc ya no se


necesita, puede ser liberada mediante la función free: void free (void* ptr);

★ La función calloc cumple la misma función que malloc(), con una diferencia:
calloc() si inicializa a 0 el contenido de cada elemento del array dinámico.

★ La función realloc intenta cambiar el tamaño de un bloque de memoria


previamente asignado. El nuevo tamaño puede ser más grande o más pequeño. Si el
bloque se hace más grande, entonces el contenido anterior permanece sin cambios y
la memoria es agregada al final del bloque. Si el tamaño se hace más pequeño
entonces el contenido sobrante permanece sin cambios.

★ La función memset de C *memset(void *str, int c, size_t n) copia el caracter c


(un char sin signo) a los primeros n caracteres de str.
Casos de estudio: tipos de memoria caché

Memoria caché
la memoria más cara y pequeña del sistema. Esta memoria no es única si no que
encontramos tres tipos diferentes de memoria caché en un mismo procesador L1, L2 y
L3. Cada uno de estas memorias tiene diferentes tamaños y velocidades, pero siempre
son más rápidos que la memoria RAM.

★ Memoria caché L1: Es el módulo de memoria más caro, opera a la misma frecuencia
que el procesador, y el más pequeño. Se utiliza una memoria L1 para datos y otra para
instrucciones, aunque siempre se hace referencia a esta como una sola. Esta memoria caché se
encuentra dentro de cada uno de los núcleos del procesador, por lo que tendremos tantos
módulos L1 como núcleos tenga la CPU.

★ Memoria caché L2: Esta memoria no es tan cara como la memoria L1, pero sigue
teniendo un elevado precio. No opera a la misma frecuencia que el procesador, pero si a una
muy cercana. Esta memoria podemos encontrarla de dos formas: compartida por todos los
núcleos o junto en cada núcleo del procesador. Tipos de memoria caché

★ Memoria caché L3: La memoria más barata de los tres tipos L de la caché. Esta
última caché es también cara pero, debido a que no opera a tan alta frecuencia como la L1 y
L2, su precio se reduce. Esta memoria es la que tiene mayor tamaño y la que comparten todos
los núcleos del procesador. En el Intel Core i7 8700K su memoria caché L3 es de 12MB.

Casos de estudio: Herramientas de Linux

Uso de herramientas de Linux

★ Linux Perf: puede obtener varios datos desde aquellos que son parte del
sistema o bien procesos realizados por el usuario. Proporciona contadores de
hardware, puntos de rastreo (tracepoints), contadores de performance de software,
pruebas dinámicas, entre otros. La mayoría de la funcionalidad de Perf se encuentra
integrada desde el kernel.

★ Likwid: es un conjunto de herramientas por línea de comandos muy fácil de


utilizar en Linux. "Likwid" significa "Like I knew what I am doing". Contiene las
siguientes herramientas: likwid-topology, que muestra la topología de la caché; likwid-
perfctr, que mide los contadores de performance del hardware en procesadores Intel y
AMD; etc. Funciona con cualquier kernel de Linux estándar y es muy liviano.

★ OProfile: es un proyecto open source que incluye un perfilador estadístico


para sistemas Linux, capaz de perfilar un código que está en ejecución con baja
sobrecarga. OProfile está disponible bajo licencia GNU GPL.

También podría gustarte