Esta página pretende explicar de uma forma suscita, o funcionamento da Gestão de Memória Virtual e os dois métodos por si utilizados: a Segmentação e a Paginação.
-Objectivos
O objectivo da segmentarão é
a divisão dos programas em segmentos lógicos que reflictam a
sua subdivisão funcional. Por exemplo, cada rotina ou cada
módulo corresponderá a um segmento.O principal objectivo deste
método é tentar suportar directamente na gestão de memória as
abstracções comuns nas linguagens de programação,
nomeadamente:
-Mecanismos de tradução de endereços
Um endereço virtual tem a
seguinte forma
(segmento, deslocamento)
segmento contém o numero do segmento e deslocamento indica o
deslocamento dentro do segmento.O mecanismo de tradução está
representado na fig. 4.5. Existe uma tabela de segmentos composta
pelo descritor de cada segmento. Cada descritor contém o
endereço físico
do segmento (endereço base do segmento), a sua dimensão, informação respeitante à protecção e à utilização do segmento. Dois registos da unidade de gestão de memória, chamados registo Base da Tabela de Segmentos (BTS) e registo Limite da Tabela de Segmentos (LTS), contêm respectivamente o endereço real de início da tabela e a sua dimensão. Quando o programa gera um endereço, o número do segmento é comparado com o registo LTS. Se for inferior, é somado com o registo BTS obtendo-se a entrada na tabela de segmentos correspondente a este segmento. De seguida, os bits de protecção são testados para verificar se o acesso pretendido é legal. habitualmente, estes bits indicam se se pode ler, escrever ou executar o segmento. Por fim, é verificado se o deslocamento pretendido é inferior ou igual à dimensão do segmento. Se o endereço for válido, o deslocamento é somado ao endereço físico do início do segmento, obtendo-se o endereço físico pretendido.Se algum dos testes anteriores falhar, isso significa que o endereço é inválido.O hardware interrompe a tradução do endereço e gera uma excepção, que será tratada pelo sistema operativo. O mecanismo descrito é executado pelo hardware. A função do sistema operativo é a de programar os vários registos, preencher a tabela de segmentos e tratar as excepções quando estas são desencadeados.Quando se dá uma mudança de contexto, os registos base e limite têm de ser carregados, com o endereço e dimensão da tabela de segmentos do novo processo.A dimensão máxima de um segmento está associada à arquitectura da máquina, não podendo nunca ser alterada porque determina quantos bits do endereço são necessários para especificar o deslocamento econter a dimensão do segmento.quantos bits são necessários no descritor para
-Optimização do Mecanismo de Tradução de Endereços
A tabela de segmentos está em memória física. Se o hardware tiver de lhe aceder de cada vez que o programa gera um endereço, o custo do acesso a uma posição de memória duplica, visto que são necessários dois acessos a memória por cada um pretendido pelo programa. Este facto é particularmente importante, porque na moderna tecnologia a velocidade de um computador está em grande parte limitada pelos acessos à memória. Em arquitecturas segmentadas a solução habitual para este problema é guardar em registos, de acesso muito rápido, as entradas da tabela de segmentos correspondentes aos segmentos em utilização. Um programa pode ter mais que um segmento de código ou dados. Da primeira vez que um segmento é acedido, o seu descritor é lido da tabela de segmentos e é guardado no registo apropriado. Por exemplo, a instrução de chamada a uma rotina noutro segmento, da forma far call segmento:deslocamento, provoca o carregamento do descritor relativo a segmento no registo associado ao segmento de código (CSR). Nos acessos seguintes a endereços dentro do mesmo segmento, a tradução é feita internamente ao processador usando o registo CSR, o que é muito rápido. A operação demorada, que é ler o descritor da tabela de segmentos, só é efectuada da primeira vez que o segmento for acedido. Se o programa aceder a outro segmento diferente de código, esse descritor será carregado em CSR, destruindo o que lá estava, Estes registos funcionam pois como uma cache de direcção unitária.Certos processadores têm tabelas genéricas, que guardam os descritores dos últimos segmentos acedidos pelo programa.
A segmentação gera fragmentação externa a medida que os segmentos são alocados e libertados. Uma maneira de a resolver é copiar todos os segmentos para um dos extremos da memória, como no caso das partições variáveis. Outra solução, usada principalmente quando um segmento cresce, é copiar o segmento para memória secundária, libertar o seu espaço em memória física, alocar um segmento da dimensão pretendida (eventualmente esperando que outros processos terminem e libertem memória) e, copiar o segmento novamente para memória primária. Ambas as soluções exigem que o processamento seja interrompido. A segunda solução é incremental, o que implica paragens menores e necessita de menos memória livre para operar.
Numa arquitectura segmentada a unidade de protecção é o segmento. A protecção associada ao segmento está especificada no descritor do segmento e é feita a vários níveis:
-Partilha de memória entre processos
Partilhar um segmento entre dois ou mais processos é externamente simples: basta ter nas varias tabelas de segmentos uma entrada contendo o mesmo endereço físico e dimensão. Desta forma, dois processos podem aceder por endereços virtuais (eventualmente diferentes) à mesma memória física.
-Objectivos
O principal objectivo da arquitectura de memória paginada é oferecer ao programador um espaço de endereçamento (virtual) linear, em geral bastante maior que a dimensão da memória física da máquina. A ideia subjacente é fazer com que o programador não precise de se preocupar com a gestão de memória quando escreve um programa.
-Mecanismos de tradução de endereços
A memória é dividida em
blocos todos do mesmo tamanho, chamados páginas sem
preocupações com a estrutura lógica do programa. Um endereço
tem a forma
(página, deslocamento)
página contém o número da página e deslocamento indica o
deslocamento dentro da página.
O mecanismo de tradução está representado na fig. 4.6, sendo
semelhante ao apresentado para a memória segmentada. Existe uma
tabela de páginas composta pelo descritor de cada página, em
geral chamado PTE (de Page Table Eníry). Cada descritor contém
o endereço físico da página, um bit de presença e
informação respeitante à protecção e à utilização da
página. Não é
necessário
guardar a dimensão das páginas, pois elas têm todas o mesmo
tamanho. Dois registos do hardware de tradução de endereços,
chamados Base da Tabela de Páginas (BTP) e Limite da Tabela de
Páginas (LTP), contêm respectivamente o endereço real de
início da tabela de páginas e a dimensão desta. Quando o
programa gera um endereço, o número da página é comparado com
registo LTP. Se for inferior, é somado com o registo BTP,
obtendo-se a entrada na tabela de páginas correspondente a esta
página. De seguida, os bits de protecção são testados para
verificar se o acesso pretendido é legal, estes bits indicam se
se pode ler, escrever ou executar a página. Se o endereço for
válido, o deslocamento é somado ao endereço físico do início
da página, obtendo-se o endereço físico pretendido. Se n for o
número de bits do deslocamento, o endereço físico do início
da página terá sempre os n bits de menor peso a zero, sendo a
soma idêntica a uma concatenação.
Como no caso da segmentarão, se algum dos testes anteriores
falhar, isso significa que o endereço é inválido, sendo gerada
urna excepção que será tratada pelo sistema operativo.
Existe uma (ou mais) tabela(s) de páginas, por processo. Quando
se dá uma mudança de contexto, os (vários) registos base e
limite têm de ser carregados com o endereço e dimensão da(s)
tabela(s) de paginas do novo processo.
A divisão das páginas está definida na arquitectura da
máquina, não podendo nunca ser alterado o espaço de
endereçamento virtual.
-Tabela de tradução de endereços(TLB)
A tabela de páginas reside em
memória física. Tal como na segmentarão, o mecanismo de
tradução obriga a um acesso suplementar à memória, o que
duplicaria o tempo de acesso à informação, tornando
indispensável a existência de uma tabela interna à unidade de
gestão de memória que guarde as PTE das, ultimas páginas
acedidas. No entanto, neste caso não podemos ter registos que
memorizem os descritores de alguns blocos lógicos do programa,
como na segmentarão. As páginas subdividem o programa
aleatoriamente, sem terem em conta blocos lógicos, pelo que
nunca é possível saber se a palavra a que queremos aceder está
ou não dentro da página actual.
A solução comum consiste em guardar numa memória associativa
de acesso muito rápido chamada TLB (Translation Lookaside
Buffer) os, descritores das últimas n páginas, acedidas pelo
programa. Quando o programa gera um endereço, a memória
associativa consulta simultaneamente todas a suas posições,
pesquisando se tem uma entrada cujo número de página seja igual
ao número de página gerado pelo programa. O acesso é feito em
paralelo a todas as posições da memória associativa. Se for
encontrada a entrada pretendida ela é colocada na saída, se
não for encontrada isso é assinalado ao hardware de gestão de
memória.
Em processadores onde a TLB é gerida pelo hardware, a pesquisa
na TLB é lançada em paralelo com o acesso à tabela de
páginas. Se o descritor for encontrado na TLB, é interrompido o
acesso à tabela de páginas. Se nãofor encontrado, a tabela de
páginas, é acedida como foi descrito anteriormente, e o
descritor é introduzido na TLB, geralmente segundo uma
disciplina FIFO, de forma a que acessos subsequentes à mesma
página sejam aí resolvidos. Outros processadores, sobretudo
processadores R,ISC, gerem a TLB por software. Se o descritor da
página não for encontrado na TLB é gerada uma excepção,
tendo o sistema operativo que preencher a entrada na TLB com o
valor adequado. Este mecanismo está representado na fig. 4.7.
O ideal seria guardar na TLB não as últimas, mas as próximas
páginas a que o programa irá aceder. Como isso é impossível
de prever, toma-se o funcionamento recente do programa como uma
boa previsão para o que ele fará no futuro próximo.
Concretamente, se um programa acedeu a uma página, é
expectável que os próximos acessos sejam dentro da mesma
página. A dimensão destas, tabelas é pequena, em geral (64,
128 entradas), pois o seu custo é elevado.
O objectivo central da
paginação é oferecer ao programador um espaço de
endereçamento virtual maior que a memória física do
computador. Isto é conseguido mantendo em memória física
apenas algumas páginas do programa e carregando da memória
secundária as outras páginas, quando isso for necessário.
A PTE tem um bit de presença (bit P) que indica se a página
está ou não em memória primária. Na descrição feita
anteriormente, considerou-se que o bit P estava a 1. Se o bit P
estiver a O, o hardware de gestão de memória gera uma
excepção que interrompe a instrução a meio. Diz-se então que
houve uma falta de página. O sistema operativo analisa a causa
da excepção, determina que foi uma falta de página e começa o
processamento adequado. Em primeiro lugar, terá de alocar uma
página livre em memória primária (segundo os algoritmos a
analisar no capítulo seguinte) e de seguida verifica qual o tipo
da pagina. Se é uma página nova (resultante do crescimento da
pilha, ou uma pagina de dados não inicializados), basta
preenche-la com zeros; se existe uma cópia da pagina em memória
secundária, é necessário lê-la do disco. Quando o acesso ao
disco terminar, o sistema operativo preenche a PTE com o
endereço da página, posiciona o bit P a I e coloca o processo
na fila dos executáveis. Quando o processo se voltar a executar,
irá completar (ou mesmo repetir, em certas arquitecturas ; a
instrução que tinha sido interrompida a meio. O acesso à
memória será repetido e completar-se-á correctamente pois PTF
já tem o bit P a 1.
As excepções provocadas pela UGN têm uma diferença importante
em relação às instruções que interrompem o processador no
fim de uma instrução. As excepções da gestão de memória
têm de interromper a instrução a meio e o processador tem de
ser capaz de, mais tarde, completar a instrução que foi
interrompida. O programa é seccionado em páginas
aleatoriamente, podendo acontecer que uma instrução seja
composta por mais de um octeto fique partida entre duas páginas
se a primeira página estiver presente e a segunda não, haverá
uma falta de página a da instrução. Se o processador não
fosse capaz de interromper a instrução a meio e depois
completa-la, aquela instrução ficaria perdida, e o programa
não funcionaria correctamente. Diz-se que as instruções tem de
ser recomeçáveis (de restartable ).
Em memória segmentada é também possível ter o mesmo mecanismo
de falta de segmento. Se o bit P do descritor de segmento estiver
a zero haverá uma falta de segmento. A diferença importante é
que, no caso da segmentação, só as instruções que carregam
um novo segmento podem originar uma falta de segmento. As
instruções que endereçam memória dentro do segmento não
obrigam ao carregamento de um novo segmento, portanto, nunca
podem originar uma falta de segmento. Estas instruções não
necessitam não necessitam de ser recomeçáveis, o que
representa uma simplificação considerável no hardowere do
processador. Na paginação, como se viu, todas as instruções
tem de ser recomeçáveis.
Um bloco lógico de programa (em geral, código, dados e pilha) corresponde a um conjunto de páginas, havendo fragmentação interna na ultima página de cada bloco. O desperdício de memória torna-se muito importante se as páginas forem grandes e houver muitos processos carregados em memória.
A protecção em memória paginada faz-se da mesma forma que em memória segmentada: processos distintos têm tabelas de páginas diferentes e cada página contém os modos de acesso permitidos (leitura, escrita e execução ). No entanto, a grande particularidade da protecção é a página. Para proteger um bloco lógico de um programa é necessário estabelecer essa protecção nas várias páginas que compõem o bloco, o que é mais complicado e menos elegante que na segmentação. Se o bloco a proteger for menor que a dimensão da página, a única solução é atribuir uma página inteira a esse bloco, o que provoca fragmentação interna à página.
-Partilha de memória entre processos
Para partilhar uma zona de memória entre vários processos basta ter, nas tabelas de páginas dos processos em causa, um conjunto de PTE indicando o mesmo endereço físico. Como para a protecção, este mecanismo é mais complicado e menos elegante na memória paginada que na segmentada.
Páginas pequenas têm a vantagem de diminuir a fragmentação interna, mas aumentam o número de faltas de páginas, a dimensão das tabelas de página 3 e a dimensão das listas de páginas mantidas pelo sistema operativo. Páginas grandes têm as vantagens recíprocas: tabelas de páginas menores, menos faltas de páginas, listas mais curtas, logo mais rápidas de pesquisar. Em contrapartida, aumenta o desperdício de memória e o tempo de transferência entre memória e disco.
A Segmentação
sege uma aproximação lógica, cada segmento é subdividido em
paginas. O mecanismo de tradução de endereços está
representado na figura.
O numero de segmento é usado para obter o endereço físico do
inicio da tabela de paginas do segmento, sendo a tradução do
par
(pagina,eslocamento)
feita como anteriormente. As TLB do segmento e paginas são
igualmente usadas como atras foi descrito.
A protecção e partilha de segmentos é feita como na
Segmentação pura. A partilha de apenas parte das paginas de um
segmento é possível, embora seja um pouco mais difícil de
gerir. Um endereço virtual tem 48 bits. Os 16 bits mais
significativos determinam o segmento, cuja dimensão máxima é
232 octetos. Cada segmento é subdividido em paginas de 4
Koctetos. A utilização normal desta arquitectura é fazer
corresponder um segmento para cada um dos segmentos lógicos de
um programa, que são código, dados e pilha, e dados do sistema
relativos ao processo, sendo cada um destes segmentos paginado.
Desta forma, ultrapassa-se a principal limitação da memória
segmentada, que é a dimensão máxima dos segmentos.
Folha realizada por: