# Memória Virtual

Cada aplicação tem uma visão própria do espaço de enderençamento - Memória Virtual. O espaço de endereçamento virtual, visto por cada aplicação, tem de ser mapeado no espaço de endereçamento fisico. Cada segmento é dividido em páginas (em geral de 4KB) e mapeado em memória fisica. Cada página contem informação apenas de um segmento.

vertical funcional

Memory management Unit (MMU): Composta por elementos de SW e HW, realiza o mapeamento e indica o endereço fisico de cada página virtual de cada um dos processos. Este processo é transparente para a aplicação. Assim, do ponto de vista da aplicação, todas as referências são realizadas a endereços virtuais.

# Paginação do Mapa de memória

  1. Divide-se cada segmento de cada um dos processos em páginas. Cada página contem apenas um segmento. Assim, é possivel existirem "buracos" (endereços livres) entre segmentos que advêm da dimensão do bloco e do segmento.

  2. As páginas virtuais são depois mapeadas em memória fisica.

  3. Cada processo tem uma tabela de páginas para realizar a tradução entre memória virtual e memória fisica.

Todas as referências do programa são feitas a endereços virtuais, as quais podem ser decompostas em:

vertical funcional

Offset=log2(nº de enderços)Offset = log_2(\text{nº de enderços})

Nota

Como as páginas estão sempre alinhadas em memória, o seu endereço base tem sempre offset igual a 0. Assim, podemos poupar espaço na tabela de páginas omitindo, nessa tabela, os bits de offset. Desse modo, o endereço na memória fisica é obtido concatenando o valor das páginas com o offset.

# Tabela de páginas hierarquia

A tabela de páginas é guardada na memória. Se a memória virtual tiver endereços de 64 de bits e cada página tiver 4KB vão existir 2522^{52} páginas virtuais. Cada entrada na tabela de páginas tem de conter, pelo menos, o número minimo de bits em falta para endereçar a memória fisica. Se a memória fisica tiver endereços de 64 bits e sabendo que os 12 menos significativos correspondentes ao offset, restam 52 bits. Arredondando para 8B significa que a tabela de páginas ocupa 252×8B=32PB2^{52}\times 8B = 32PB o que é imenso.

Assim, para resolver este problema, vamos paginar a tabela de páginas. Cada página é guardada em memória como se tratasse de qualquer outra página.

Como saber a localização de cada página da tabela de páginas?

\to Construir uma tabela de páginas que indica a localização da tabela de páginas.

\to Cada entrada da tabela de páginas indica a localização fisica de uma página em memória (excluindo bits de offset, já que são 0).

E se a nova tabela de páginas ainda for muito grande?

\to Repetir o processo até que a tabela de páginas de nível superior couber numa página (de modo geral = 4KB).

Como saber a localização de cada página da tabela de páginas de nivel superior?

\to Adicionar um registo especial no processador com a localização: SATP: Supervisor Address Translation and Protection.

Este registo guarda a localização em memória (endereço) da base da tabela de página de nível 0. Como cada processo tem uma tabela de tradução diferente, sempre que ocorre uma mudança de contexto, o registo SATP tem de ser atualizado com o valor correto para o novo processo.

Como existem vários niveis de tradução, agora é necessário repetir o processo de indexação n vezes, até se descobrir o endereço de memória. Em cada passo de indexação i=0,1,...,n1i={0, 1, ..., n-1} obtêm-se o endereço fisico da página a partir da entrada da tabela i1i-1 (onde PT1PT_-1 corresponde ao SATP), e consulta-se a entrada na tabela de acordo com o seu campo PTi do endereço virtual.

Nota

O acesso a uma palavra (de dados ou instrução) requer agora n acessos para obter o endereço fisico, mais 1 para obter a palavra.

# Estrutura de uma PTE (Page Table Entry)

PTE

  1. Tem a dimensão da palavra do processador.
  2. Os bits de controlo indicam os privilégios necessários para acesso à página seguinte.
  3. O campo Physical Address indica o endereço fisico da página de nivel seguinte (excluindo os n bits de offset).
Exemplos:

Consideremos um processador de 64 bits, com 33 bits de endereço físico, 43 bits de endereço virtual e páginas de 8KB. A dimensão de cada PTE é de 8B. Qual o número de níveis para tradução de endereço?

Endereço Virtual:

Offset=log2(8KB)=13bits\text{Offset} = log_2(8KB) = 13 \text{bits}

Logo VPN vai ser 4313=30bits43 - 13 = 30 \text{bits}

Como cada PTE tem 8B, o número de entradas vai ser:

8KB8B=21323=21010entradas\frac{8KB}{8B} = \frac{2^{13}}{2^3} = 2^{10} \to 10 \text{entradas}

Assim, o número de níveis é dado por:

Bits do VPNEntradas=3010=3\frac{\text{Bits do VPN}}{\text{Entradas}} = \frac{30}{10} = 3

E qual será o número de bits usados pela PTE para guardar o endereço da próxima página?

O endereço de nível seguinte é:

Endereço FisicoOffset=3313=20\text{Endereço Fisico} - \text{Offset} = 33 - 13 = 20

# Estrutura de uma PTR (Page Table Root)

PTR

  1. P - bit Present: Quando P = 0, a página não está em RAM, o endereço no physical address não é válido \to Page Fault

Quando a página existe (o SO verifica) é porque esta está em disco. Ocorre o processo de troca de páginas que se denomina Page Swap. Se não existe, é porque corresponde a um acesso indevido \to Segmentation Fault

  1. A (acessed): Quando A = 0, página não é usada recentemente.

Página que pode ser movida para disco caso seja necessário realizar um page swap.

  1. D (dirty): Quando D = 1, significa que a página foi escrita.

Esta página não pode sair da memória RAM sem ser re-escrita (atualizada) em disco. Na prática a RAM funciona com uma politica Write-Back, Write-Allocate.

  1. R/W Read/Write: Permissões de escrita na memória.

  2. EX (execute): Permissões de execução

  • EX = 1, a página contem instruções.

  • EX = 0, a página contem dados.

  1. U/S(User/Supervisor privileges): Permissões de acesso.

# TLB: Translation Lookaside Buffer

O sistema de memória virtual aumenta a latência no acesso aos dados e instruções. Para reduzir o tempo de tradução, geralmente utiliza-se uma cache TLB para acelerar a tradução.

A TLB tradicionalmente corresponde a uma cache endereçada pela virtual page number:

  • Linhas de 1 ou 2 entradas, onde cada entrada corresponde a uma PTE.

  • Associatividade elevada.

# Estrutura de uma TLB com uma PTE por linha, completamente associativa

  • Como a cache é totalmente associativa, não são usados quaisquer bits para índice.

  • Sempre que a TLB é acedida, são verificadas todas as entradas (isto é, cada entrada corresponde a uma via diferente).

  • Dado que a TLB é endereçada virtualmente, e como todos os processos têm o mesmo mapa de memória virtual, é necessário distinguir se a entrada na TLB corresponde a um processo A ou a um processo B, isto é, realizado com o campo PID - Process ID.

  • Assim, existe um HIT na TLB se:

  1. V = 1
  2. TAGTLB=TABEnd.virtualTAG_{TLB} = TAB_{End. virtual}
  3. PIDTLB=PIDprocessoPID_{TLB} = PID_{processo}