Compreensão aprofundada do princípio do cache TLB

Hoje vou compartilhar um bom artigo sobre TLB. Espero que todos solidifiquem suas habilidades básicas e nos permitam entender o sistema de computador em profundidade.

TLB é a abreviatura de Translation Lookaside Buffer. Em primeiro lugar, sabemos que o papel da MMU é converter endereços virtuais em endereços físicos.

Como funciona o MMU

A relação de mapeamento entre o endereço virtual e o endereço físico é armazenada na tabela de páginas e agora a tabela de páginas é hierárquica. Sistemas de 64 bits são geralmente de 3 a 5 níveis. Uma configuração comum é uma tabela de página de 4 níveis, portanto, vamos usar uma tabela de página de 4 níveis como exemplo. São tabelas de páginas de quatro níveis PGD, PUD, PMD e PTE. Haverá um registrador de endereço base da tabela de páginas no hardware, que armazena o primeiro endereço da tabela de páginas PGD.

Mecanismo de paginação do Linux

A MMU pesquisa todo o caminho desde a tabela de páginas PGD até o PTE de acordo com o registro de endereço base da tabela de páginas e, finalmente, encontra o endereço físico (o endereço físico é armazenado na tabela de páginas PTE). É como mostrar onde fica sua casa em um mapa. Para encontrar seu endereço residencial, primeiro verifique se você está na China, depois verifique se está em uma determinada província, continue até uma determinada cidade e, finalmente, encontre sua casa ... É o mesmo princípio. Encontre passo a passo. Você também viu esse processo, é muito complicado. Se eu descobrir a localização específica de sua casa pela primeira vez, anotarei seu nome e endereço residencial. Da próxima vez que você pesquisar, basta me dizer qual é o seu nome, e eu poderei lhe dizer o endereço diretamente, sem precisar pesquisar nível por nível.

O processo de pesquisa de tabela de página de quatro níveis requer quatro acessos à memória. O atraso pode ser imaginado, o que afeta muito o desempenho. Um exemplo do processo de pesquisa da tabela de páginas é mostrado na figura abaixo. Haverá uma chance de expandir em detalhes no futuro, basta aprender sobre isso aqui.

caminhada na mesa de página

Qual é a natureza do TLB

O TLB é na verdade um cache.

Cache de dados endereço de cache (endereço virtual ou endereço físico) e dados. O TLB armazena endereços virtuais e seus endereços físicos mapeados. O TLB pesquisa o cache com base no endereço virtual e não tem escolha a não ser procurar com base no endereço virtual.

Portanto, o TLB é um cache virtual. Depois que o TLB existe no hardware, o processo de tradução do endereço virtual para o endereço físico foi alterado. O endereço virtual é enviado primeiro ao TLB para confirmar se ele atinge o cache e, se o cache atingir, o endereço físico pode ser obtido diretamente.

Caso contrário, consulte a tabela de páginas nível por nível para obter o endereço físico. E armazene em cache o relacionamento de mapeamento entre o endereço virtual e o endereço físico no TLB. Como o TLB é um cache virtual (VIVT), há problemas de aliasing e ambiguidade? Em caso afirmativo, como o software e o hardware trabalham juntos para resolver esses problemas?

TLB especial

A menor unidade de endereço físico de mapeamento de endereço virtual é 4 KB. Portanto, o TLB não precisa realmente armazenar os 12 bits inferiores do endereço virtual e o endereço físico (como os 12 bits inferiores são os mesmos, não há necessidade de armazená-los).

Além disso, se atingirmos o cache, devemos retirar todos os dados do cache de uma só vez. Portanto, o endereço virtual não precisa do campo de deslocamento. O campo de índice é obrigatório? Depende de como o cache está organizado.

Se for um cache totalmente associativo. Então não há necessidade de index. Se estiver usando um cache associado ao conjunto multidirecional, um índice ainda será necessário.

A figura abaixo é um exemplo de um TLB associado a um conjunto de quatro vias. A faixa de endereçamento de CPU de 64 bits de hoje não é estendida para 64 bits. O espaço de endereço de 64 bits é muito grande e não é tão grande hoje.

Portanto, para simplificar o projeto ou resolver o custo do hardware, apenas uma parte dos bits de endereço virtual reais é usada. Aqui, tomamos o barramento de endereços de 48 bits como exemplo.

Problema de aliasing com TLB

Deixe-me pensar sobre a primeira pergunta primeiro, se o pseudônimo existe. Sabemos que não há problema de alias no cache de dados do PIPT. O endereço físico é único e um endereço físico deve corresponder a um dado. Mas diferentes endereços físicos podem armazenar os mesmos dados.

Ou seja, os dados correspondentes ao endereço físico são uma relação um-para-um e vice-versa é uma relação muitos-para-um. Devido à particularidade do TLB, a correspondência entre endereços virtuais e endereços físicos é armazenada.

Portanto, para um único processo, um endereço virtual corresponde a um endereço físico ao mesmo tempo, e um endereço físico pode ser mapeado por vários endereços virtuais.

Comparando o cache de dados PIPT com o TLB, podemos saber que não há problema de alias no TLB. No entanto, há um problema de alias no VIVT Cache, porque VA precisa ser convertido em PA e os dados são armazenados em PA. Há muitas histórias no meio, então alguns problemas foram introduzidos.

Problema de ambiguidade TLB

Sabemos que o intervalo de endereço virtual visto entre diferentes processos é o mesmo, portanto, em vários processos, o mesmo endereço virtual de diferentes processos pode ser mapeado para diferentes endereços físicos. Isso cria problemas de ambigüidade.

Por exemplo, o processo A mapeia o endereço 0x2000 para o endereço físico 0x4000. O processo B mapeia o endereço 0x2000 para o endereço físico 0x5000. Quando o processo A for executado, armazene em cache o relacionamento de mapeamento entre 0x2000 e 0x4000 no TLB. Quando o processo B é alternado, o processo B acessa os dados em 0x2000 e buscará dados do endereço físico 0x4000 devido a um acerto de TLB.

Isso cria ambiguidade. Como eliminar essa ambigüidade, podemos aprender com o método de processamento do cache de dados VIVT e invalidar todo o TLB durante a comutação do processo. Nenhum dos processos comutados atingirá o TLB, mas resultará em perda de desempenho.

  Informações por meio do trem: rota de aprendizado da tecnologia de código-fonte do kernel do Linux + tutorial em vídeo do código-fonte do kernel

Learning through train: Linux kernel code memory tuning file system process management device driver/network protocol stack

Como evitar flush TLB tanto quanto possível

A primeira coisa que precisa ser explicada é que o flush aqui é entendido como invalidante. Sabemos que quando o processo é trocado, para evitar ambigüidade, precisamos liberar ativamente todo o TLB. Flush TLB pode ser evitado se pudermos distinguir entradas TLB de diferentes processos.

Sabemos como o Linux distingue diferentes processos e cada processo tem um ID de processo exclusivo. Seria ótimo se o TLB comparasse o ID do processo além da tag ao julgar se foi atingido ou não! Desta forma, as entradas TLB de diferentes processos podem ser distinguidas.

Embora o processo A e o processo B tenham os mesmos endereços virtuais, mas as IDs do processo sejam diferentes, naturalmente o processo B não atingirá a entrada TLB do processo A. Portanto, o TLB adiciona uma correspondência ASID (ID do espaço de endereço).

ASID é semelhante ao ID do processo, que é usado para distinguir entradas TLB de diferentes processos. Dessa forma, não há necessidade de descarregar o TLB quando o processo for trocado. Mas o software ainda é necessário para gerenciar e atribuir ASIDs.

Como gerenciar ASIDs

ASID e ID do processo definitivamente não são os mesmos, não confunda os dois. O ID do processo pode ter uma ampla gama de valores. Mas o ASID geralmente é de 8 ou 16 bits. Portanto, apenas 256 ou 65536 processos podem ser distinguidos. Nosso exemplo é ilustrado com um ASID de 8 bits.

Portanto, é impossível para nós ter uma correspondência de um para um entre o ID do processo e o ASID. Devemos atribuir um ASID a cada processo, e o ID do processo e o ASID de cada processo geralmente não são iguais.

Sempre que um novo processo é criado, é atribuído a ele um novo ASID. Depois que o ASID for alocado, elimine todos os TLBs e realoque o ASID.

Portanto, se você quiser evitar liberar completamente o TLB, idealmente, o número de processos em execução deve ser menor ou igual a 256. No entanto, esse não é o caso, portanto, é necessária uma combinação de software e hardware para gerenciar ASIDs.

Para gerenciar cada processo, o kernel do Linux terá uma estrutura task_struct, onde podemos armazenar o ASID atribuído ao processo atual. O registrador de endereços base da tabela de páginas possui bits livres que também podem ser usados ​​para armazenar o ASID. Quando o processo é alternado, o endereço base da tabela de páginas e o ASID (que pode ser obtido em task_struct) podem ser armazenados juntos no registrador de endereço base da tabela de páginas.

Ao pesquisar o TLB, o hardware pode comparar a tag e o ASID para igualdade (compare o ASID armazenado no registro de endereço base da tabela de páginas com o ASID armazenado na entrada do TLB). Se todos forem iguais, isso significa que o TLB foi atingido. Caso contrário, o TLB falhará. Quando o TLB falha, é necessário percorrer a tabela de páginas em vários níveis para encontrar o endereço físico. Em seguida, ele é armazenado em cache no TLB e o ASID atual é armazenado em cache ao mesmo tempo.

compartilhado por vários processos

Sabemos que o espaço do kernel e o espaço do usuário são separados e o espaço do kernel é compartilhado por todos os processos. Como o espaço do kernel é compartilhado, quando o processo A troca o processo B, se o endereço acessado pelo processo B estiver no espaço do kernel, o TLB armazenado em cache pelo processo A pode ser usado. Mas agora, como o ASID é diferente, isso leva à falta de TLB.

Nosso mapeamento compartilhado global para o espaço do kernel é chamado de mapeamento global. Os mapeamentos para cada processo são chamados de mapeamentos não globais.

Portanto, introduzimos um bit (bit não global (nG)) no último nível da tabela de páginas para representar se é um mapeamento global. Quando o relacionamento do endereço físico do mapeamento de endereço virtual é armazenado em cache no TLB, o bit nG também é armazenado.

Ao julgar se deve acertar o TLB, ao comparar as tags são iguais, julgue se é um mapeamento global, em caso afirmativo, julgue diretamente o acerto do TLB sem comparar o ASID. Quando não é um mapeamento global, o ASID é finalmente comparado para determinar se o TLB atingiu.

Quando o TLB deve ser lavado

Vamos ao resumo final, quando deve liberar o TLB.

  • Quando os ASIDs são alocados, todos os TLBs precisam ser liberados. ASIDs podem ser gerenciados usando bitmaps, e todos os bitmaps devem ser limpos após a liberação dos TLBs.
  • Quando criamos um mapeamento de tabela de páginas, precisamos liberar a entrada TLB correspondente ao endereço virtual. A primeira impressão pode ser que o flush TLB é necessário apenas quando o mapeamento da tabela de páginas é modificado, mas a situação real é que o flush TLB é necessário desde que o mapeamento seja estabelecido. A razão é que quando você cria um mapeamento, você não sabe se existe um mapeamento antes. Por exemplo, se você criar um mapeamento do endereço virtual A para o endereço físico B, não sabemos se existe um mapeamento de endereço virtual A para endereço físico C antes, então é unificado em Flush TLB ao estabelecer um relacionamento de mapeamento.

Autor do texto original: [ Aprenda Embedded Together

 

Acho que você gosta

Origin blog.csdn.net/youzhangjing_/article/details/132088646
Recomendado
Clasificación