Escritos
B. Piropo
Anteriores:
< Trilha Zero >
Volte de onde veio
02/12/1996

< Memórias XV: >
< Cache Hits >


Agora que sabemos que cache é uma porção de memória de acesso rápido interposta entre a CPU e a memória principal para acelerar o desempenho da máquina, vamos ver como a coisa funciona. Mas antes de prosseguirmos, um aviso: enquanto estivermos discutindo cache, evitarei traduzir os termos técnicos do inglês. Ao invés de tentar a tarefa - a meu ver impossível - de descobrir uma tradução decente para "write through" por exemplo (incidentalmente: quem conhecer alguma, favor informar), procurarei explicar o que é e para que serve a coisa. Isto posto, ao trabalho.

O cache é composto por dois conjuntos de chips de memória estática (SRAM) de acesso rápido. O primeiro conjunto chama-se "data store" e armazena dados. O segundo chama-se "tag store" e armazena informações sobre os dados armazenados no primeiro. Parece complicado, mas logo você perceberá que é cristalinamente simples.

O cache armazena dados grupados em blocos de bytes, ou "linhas". Nas máquinas modernas cada linha é composta por 16 bytes, em virtude do modo pelo qual os novos processadores de 32 bits manejam dados. O tipo mais simples de cache é o "direct mapped", onde a memória é subdividida em blocos do mesmo tamanho que o cache. Cada vez que a CPU lê uma "linha" na memória, seu conteúdo é transcrito no data store exatamente no lugar correspondente à sua posição no bloco de memória de onde ela foi lida. E a posição (ou "índice") desta linha é gravada no tag store.

Vamos ver um exemplo para ilustrar. Imagine que sua máquina tenha 8 Mb de memória RAM e 256 K de cache, uma configuração comum nos dias de hoje. A memória principal é, então, dividida em 32 blocos de 256 K cada. Vamos supor que a CPU tenha efetuado a leitura de uma linha na memória principal, digamos, a décima linha do quinto bloco. Enquanto os dados são transferidos para a CPU, o circuito controlador do cache copia os 16 bytes da linha no data store, exatamente na posição correspondente à ocupada pela linha no bloco de onde ela foi lida (ou seja: a cópia vai ocupar a décima linha do cache). E depois copia na décima posição do tag store o número do bloco de onde a linha foi lida, no caso o número cinco.

Evidentemente, depois de algum tempo o tag store está totalmente ocupado por índices e o data store cheio de "linhas", cópias exatas das linhas correspondentes da memória principal. A diferença é que no cache as linhas podem estar "embaralhadas", ou seja, depois da décima linha do, digamos, quinto bloco da memória principal, pode estar armazenada a décima-primeira linha do vigésimo bloco. E depois dela a décima-segunda linha do terceiro bloco e assim por diante. Parece confuso, mas não é: a qualquer momento pode-se saber de que bloco veio aquela linha consultando o tag store, que armazena os índices dos blocos de onde cada linha foi copiada.

Agora imagine que o data store está cheio de dados e a CPU solicita que o conteúdo de um determinado endereço de memória seja lido. Antes que o circuito de controle da memória RAM comece a procurar o dado, o controlador do cache intercepta o endereço e verifica a que linha de que bloco ele pertence. Em seguida, consulta o tag store e verifica se na posição correspondente à linha solicitada está armazenado o número do bloco no qual a CPU solicitou a leitura. Se os números coincidirem, bingo: o cache contém uma copia exata da linha onde está o dado solicitado. É então declarado um acerto no cache (cache hit) e o dado é fornecido imediatamente à CPU, numa fração do tempo que seria gasto para lê-lo da memória RAM.

Descrito desta forma parece que um acerto no cache depende de muita sorte. No nosso exemplo, a memória foi subdividida em 32 blocos. Como o dado solicitado pode estar em qualquer um destes blocos, aparentemente a probabilidade de um cache hit é de 1:32, pouco maior que a de acertar um número na roleta, que é de 1:37. Mas as aparências enganam. Porque na roleta (pelo menos nas roletas honestas) não há ligação entre dois números sucessivos, enquanto a imensa maioria dos acessos à memória é feita em endereços contíguos. Em conseqüência disto o data store vai se enchendo de cópias de dados contidos em endereços muito próximos. Resultado: a probabilidade estatisticamente comprovada de um cache hit é da ordem de 98%. Ou seja: de cada cem acessos, apenas dois corresponderão a dados que não estão no cache e, portanto, devem ser lidos na lenta memória RAM. Nos 98 acessos restantes, haverá cópias dos dados no data store, que serão fornecidas à CPU muito mais rapidamente. E como, no uso diário, a maior parte do tempo gasto por nossas máquinas é consumida em acessos à memória, seu desempenho melhora consideravelmente com o uso do cache.

Hoje vimos como a coisa funciona quando os dados são lidos na memória. Semana que vem veremos o que acontece quando a CPU solicita que um dados seja escrito.

 

B. Piropo