Memória virtual e tradução
Relocação, fragmentação, segmentação, páginas, tabelas e TLB.
O pai e o filho podem usar o endereço virtual 0x1000 para dados privados diferentes. A MMU, unidade de gestão de memória, traduz cada acesso com o mapa do processo e verifica permissões. Seguiremos um endereço desde a separação em página e deslocamento até à moldura física, distinguindo o custo da tradução do custo de trazer dados para RAM.
Hierarquia de memória
Os registos guardam operandos junto da CPU. As caches conservam cópias de dados e instruções para reduzir acessos à RAM. A RAM guarda as páginas residentes; ficheiros e swap podem guardar dados que terão de ser preparados antes do uso. Em geral, os níveis mais próximos da CPU têm menor capacidade e menor latência.
Uma cache de dados e o TLB têm funções diferentes: a primeira guarda conteúdo; o segundo guarda traduções. Um miss numa delas não prova falta na outra. Nos exercícios de tempos, identifica quais destes custos o modelo inclui.
Endereço virtual e físico
O endereço virtual é o que o processo usa. O físico identifica a posição na memória física. Dois processos podem usar o virtual 0x1000 e traduzi-lo para molduras diferentes. Também podem mapear uma página partilhada em endereços virtuais distintos.
A associação pode acontecer em compilação, se o destino estiver fixo; no carregamento, se o código for relocável; ou em execução, com tradução por hardware. A tradução em execução permite mudar a colocação física sem mudar os endereços usados pelo programa.
O tamanho máximo do espaço virtual não mede RAM atribuída. Páginas podem estar ausentes, regiões podem não ter mapeamento e o hardware pode implementar menos bits de endereço do que a largura dos registos. Um registo de 64 bits não garante bytes utilizáveis pelo processo.
Base, limite e alocação contígua
Num modelo simples, o virtual é válido se , sendo o limite em bytes. O físico é , sendo a base. Só o núcleo pode mudar estes registos.
Para e , traduz para 13500; é inválido, apesar de a soma 14000 existir. O limite é exclusivo neste modelo.
Na alocação contígua, cada processo ocupa uma região física. Parte de um buraco de 500 KiB para um pedido de 212: ficam 288 livres, mas noutra posição da lista. É esta evolução dos buracos que a tabela regista passo a passo. First-fit escolhe o primeiro suficiente, best-fit o menor suficiente e worst-fit o maior.
Com buracos de 100, 500, 200, 300 e 600 KiB, por esta ordem, uma sequência de pedidos 212, 417 e 112 KiB dá:
| Política | Colocação de 212 | Colocação de 417 | Colocação de 112 |
|---|---|---|---|
| First-fit | Buraco 500, sobram 288 | Buraco 600, sobram 183 | Resto 288, sobram 176 |
| Best-fit | Buraco 300, sobram 88 | Buraco 500, sobram 83 | Buraco 200, sobram 88 |
| Worst-fit | Buraco 600, sobram 388 | Buraco 500, sobram 83 | Resto 388, sobram 276 |
Fragmentação externa significa haver espaço total mas não uma região contígua suficiente. Fragmentação interna é espaço dentro de uma unidade atribuída que não é usado. Compactar aproxima regiões ocupadas para reunir buracos, mas exige relocação adequada e cuidado com I/O em curso.
Segmentação
Um endereço segmentado contém número de segmento e deslocamento. A tabela guarda base, limite e permissões de cada segmento. O segmento pode representar código, dados ou pilha e ter dimensão diferente dos restantes.
Para o segmento 2 com base 8000 e limite 400, o par (2, 350) traduz para 8350. (2, 400) viola o limite. Segmentos de tamanho variável podem sofrer fragmentação externa. Paginação e segmentação também podem ser combinadas: primeiro identificar a região lógica, depois traduzir as suas páginas.
Paginação
O espaço virtual divide-se em páginas de tamanho bytes. A RAM divide-se em molduras do mesmo tamanho. Uma tabela de páginas indica que moldura corresponde a cada página virtual e guarda estado e permissões.
Para um endereço virtual :
é a página, o deslocamento, a moldura e o físico. O deslocamento passa sem alteração porque indica a posição dentro da página, e as páginas têm todas o mesmo tamanho. Com endereços de bits, bits ficam para o deslocamento e para a página.
Com páginas de 4 KiB, . O virtual 0x1A3F5 divide-se em página 0x1A e deslocamento 0x3F5. Se a página está na moldura 0x07, obtemos 0x073F5. Em decimal, .
Na demo, o espaço virtual tem 64 bytes e a tabela associa as páginas às molduras 3, 0, 5, 1, 7, 2, 6 e 4. Para cada tamanho, só usamos as primeiras entradas da tabela. Todas as páginas do espaço têm permissão de leitura. Muda o tamanho da página e observa que o mesmo endereço passa a ter outra decomposição. Desmarcar presença representa uma página válida que ainda precisa de ser preparada, não um endereço proibido.
Tabela usada: página 0 → moldura 3; 1 → 0; 2 → 5; 3 → 1; 4 → 7; 5 → 2; 6 → 6; 7 → 4. Só as primeiras 64/P entradas pertencem ao espaço virtual.
Com página de 16 bytes e virtual 45, , , e físico 93. Este modelo não simula caches nem o custo de uma falta de página.
Fragmentação e tamanho das tabelas
Um objeto de 10000 bytes, assumindo uma região alinhada ao início de página, precisa de páginas. São 12288 bytes de capacidade, com 2288 não usados no fim. A paginação evita exigir contiguidade entre as molduras atribuídas ao processo, mas conserva fragmentação interna.
Uma tabela linear para 32 bits e páginas de 4 KiB tem entradas. Com 4 bytes por entrada, ocupa 4 MiB. Páginas maiores reduzem o número de entradas e podem melhorar o alcance do TLB, mas podem aumentar desperdício interno.
Uma tabela multinível reparte o índice. Com 32 bits, páginas de 4 KiB e entradas de 4 bytes, um bloco de tabela guarda entradas, selecionadas por 10 bits. Dividimos os 20 bits de página em dois campos de 10; os 12 restantes continuam a ser o deslocamento.
O endereço 0x00403F5D decompõe-se assim:
| Campo | Cálculo | Valor |
|---|---|---|
| Índice exterior | 1 | |
| Índice interior | 3 | |
| Deslocamento | 0xF5D = 3933 |
A entrada exterior 1 aponta para uma tabela interior. Se a entrada 3 dessa tabela indicar a moldura 7, o físico é , ou 0x7F5D. Os índices escolhem onde procurar a tradução; não se somam à moldura.
Se só esta região de 4 MiB estiver mapeada com páginas normais, basta uma tabela exterior e uma interior: 8 KiB de tabelas, em vez dos 4 MiB da tabela linear completa. As outras entradas exteriores podem indicar regiões sem tabela. O percurso pode exigir duas leituras de tabela antes do dado quando não há TLB nem caches de percurso.
Uma tabela hashed pesquisa por número de página virtual e identifica a tradução nas colisões. Uma tabela invertida guarda uma entrada por moldura física, incluindo a identidade do processo e da página. Poupa espaço para espaços virtuais enormes, mas muda o custo de pesquisa e exige representar partilhas.
TLB e tempo efetivo
O TLB é uma cache de traduções. Um miss obriga a obter a tradução; não significa que o dado esteja fora da RAM. Uma falta de página é outra situação. Identificadores de espaço, como ASID, podem distinguir entradas de processos; sem isso pode ser necessário invalidá-las ao mudar de contexto.
Suponhamos uma tabela de um nível, acesso ao TLB de ns, memória de ns, taxa de acerto , sem caches adicionais nem faltas de página. Um acerto custa ns; um miss custa ns:
Não apliques esta fórmula sem verificar o modelo. Se a consulta ao TLB estiver incluída no tempo de acesso, não a somes outra vez. Tabelas multinível ou caches de percursos mudam o custo do miss.
O alcance do TLB é aproximadamente número de entradas vezes tamanho de página. 64 entradas de 4 KiB cobrem 256 KiB de páginas distintas. Ultrapassar esse alcance pode aumentar misses do TLB sem aumentar faltas de página.
Presença, permissões e partilha
Uma página pode estar mapeada mas ausente da RAM, presente mas só para leitura, ou não pertencer ao espaço válido. As designações valid e present variam entre modelos; lê a definição do bit no enunciado. Não uses um único bit para concluir que toda a ausência é acesso ilegal.
Código imutável de bibliotecas pode partilhar molduras entre processos com proteção contra escrita. Dados privados depois de fork podem partilhar molduras apenas até uma escrita provocar copy-on-write. A próxima página explica o que acontece quando faltam molduras e é preciso substituir páginas.
Exercícios
Conservar o deslocamento
Páginas de 4096 bytes. O endereço virtual é 0x1A3F5 e a página 0x1A está na moldura 7, presente e legível. Qual é o endereço físico em decimal?
Pista
Solução
7 × 4096 + 1013 = 29685, equivalente a 0x073F5. Traduz-se a página e conserva-se o deslocamento.
Erros frequentes
Multiplicar o endereço virtual inteiro pela moldura ou substituir os bits do deslocamento.
Contar entradas e bytes
Um espaço virtual de 32 bits usa páginas de 4 KiB e entradas de 4 bytes numa tabela linear completa. Quantos MiB ocupa a tabela?
Pista
Divide o espaço virtual pela página antes de multiplicar pelo tamanho da entrada.
Solução
2^20 × 4 = 2^22 bytes = 4 MiB. Esta é uma tabela linear completa, não um total de RAM de dados do processo.
Erros frequentes
Contar molduras físicas em vez de páginas virtuais, ou confundir MiB com milhões decimais.
Custo de tradução e página presente
A consulta ao TLB demora 5 ns; cada acesso a RAM demora 80 ns. Há duas tabelas de páginas no percurso, taxa de acerto no TLB de 90%, páginas presentes e legíveis, sem outras caches. Calcula o custo de um acerto, de um miss e o tempo efetivo. O miss exige ler dados do disco?
Pista
Solução
No acerto, a tradução vem do TLB e resta ler o dado: 5+80=85 ns. No miss, consultamos duas tabelas e depois o dado: 5+3×80=245 ns. A média é 0,9×85+0,1×245=101 ns.
Não há falta de página neste modelo: páginas e tabelas estão na RAM. O TLB guarda traduções, portanto faltar uma tradução nessa cache não implica I/O de paginação.
Confere a tua resposta:
- Separei miss do TLB de falta de página.
- Obtive 85 ns para acerto e 245 ns para miss.
- Ponderei os casos e obtive 101 ns.
Espaço total sem um buraco suficiente
Os buracos livres, por ordem crescente de endereço, têm 8, 14, 6 e 20 KiB. Estão separados por regiões ocupadas. Há pedidos sucessivos de 10, 6 e 12 KiB, sem libertações, alinhamentos adicionais ou compactação. A parte usada sai do início do buraco escolhido e o restante conserva a posição na lista.
Compara first-fit e worst-fit, registando os buracos após cada pedido. Se uma política falhar, indica quanto espaço total ainda está livre e por que não chega.
Solução
First-fit escolhe o buraco 14 para 10 e deixa 8,4,6,20. Para 6, escolhe o primeiro 8 e deixa 2,4,6,20. Para 12, escolhe 20 e deixa 2,4,6,8. Os três pedidos tiveram sucesso.
Worst-fit escolhe primeiro 20 e deixa 8,14,6,10. Para 6, escolhe 14 e deixa 8,8,6,10. O pedido de 12 falha: restam 8+8+6+10=32 KiB, mas o maior buraco tem 10 KiB. Não podemos somar regiões separadas para satisfazer um pedido contíguo. É fragmentação externa; nenhuma política cria espaço novo ou compacta automaticamente.
Confere a tua resposta:
- Atualizei os buracos após cada pedido de first-fit.
- Obtive falha do terceiro pedido em worst-fit apesar de 32 KiB livres.
- Identifiquei fragmentação externa, sem mover regiões implicitamente.