Políticas de cache e desempenho
Escritas, vítimas dirty, memória principal e CPI de caches separadas ou multinível.
O CPU escreve 7 no endereço 0 e volta a lê-lo. Se a cache conservar o valor novo, essa leitura pode acertar mesmo que a RAM ainda tenha o valor antigo. A política de escrita determina quando a modificação chega ao nível seguinte; a política de alocação determina o que fazer quando a escrita falha.
Write-through e write-back
Write-through (WT): uma escrita que acerta atualiza a cache e envia a escrita para o nível seguinte. Write-back (WB): altera a cache e marca a linha dirty; o nível seguinte pode ficar desatualizado até a linha ser descarregada.
Dirty não significa inválido. V=1,D=1 contém dados válidos e modificados. V=0 não é uma linha utilizável, mesmo que o bit D antigo seja 1.
O modelo WT/no-allocate não instala uma linha por uma escrita que falha. WB/allocate instala-a. São combinações frequentes, não uma equivalência lógica: política de escrita e de alocação são decisões distintas.
| Operação | WT, no-allocate | WB, allocate |
|---|---|---|
| Leitura com acerto | Ler cache | Ler cache |
| Leitura com falta | Carregar linha; V=1 | Descarregar vítima válida dirty, se houver; carregar linha; V=1,D=0 |
| Escrita com acerto | Atualizar cache e nível seguinte | Atualizar cache; D=1 |
| Escrita com falta | Escrever no nível seguinte; cache fica igual | Descarregar vítima válida dirty; instalar linha, alterar os bytes escritos; V=1,D=1 |
Em uma escrita parcial de uma linha, a alocação normalmente lê os bytes restantes do nível seguinte. No modelo adotado, se a escrita substitui a linha inteira, não é necessário lê-la antes. Por exemplo, uma cache com uma palavra por linha pode instalar uma escrita de palavra completa sem uma leitura adicional. Esta condição muda a contagem de acessos.
Um traço com vítimas modificadas
Uma falta com vítima dirty tem duas tarefas: conservar o bloco antigo e instalar o pedido. Segue cache e RAM lado a lado, pois uma leitura que acerta devolve o valor mais recente da cache. O traço usa cache direta WB com 2 linhas de 4 B, inicialmente inválida, e operações de palavra completa, com E a escrever e L a ler.
| Operação | Índice, etiqueta | Eventos no nível seguinte | Estado relevante depois |
|---|---|---|---|
| E0=7 | 0,0 | Nenhum; escrita cobre a linha | Linha 0: tag 0, V 1, D 1, valor 7 |
| L0 | 0,0 | Nenhum | Devolve 7 |
| E8=9 | 0,1 | Escrever vítima no endereço 0 | Linha 0: tag 1, V 1, D 1, valor 9 |
| L4 | 1,0 | Ler linha que começa em 4 | Linha 1: tag 0, V 1, D 0 |
| L0 | 0,0 | Escrever vítima no endereço 8 e ler linha 0 | Linha 0: tag 0, V 1, D 0, valor 7 |
Total: duas leituras e duas escritas de linhas na memória principal. O último acesso devolve 7 porque a primeira vítima já tinha atualizado a memória.
O endereço de uma vítima é reconstruído com a etiqueta antiga, o índice da entrada e deslocamento zero. Usar a etiqueta do pedido escreveria os dados da vítima no sítio errado.
Aplica WT/no-allocate ao mesmo traço. E0 escreve na RAM sem instalar nada; L0 carrega a linha 0. E8 escreve na RAM e mantém na cache o bloco 0; L4 carrega a linha 4; a última L0 acerta.
Os totais coincidem, duas escritas e duas leituras, mas por causas diferentes:
| Acesso final | WB: o que acontece | WT: o que acontece |
|---|---|---|
| L0 final | Falta; descarrega 9 e carrega 0 | Acerto na linha guardada |
| E8 | Sem tráfego; só marca dirty | Escrita direta na RAM |
No traço WB, a leitura final falha e provoca dois acessos; em WT, acerta.
Para reconstruir a vítima no acesso L0, a etiqueta antiga é 1, o índice é 0 e cada linha tem 4 B: . É nesse endereço que se descarrega 9 antes de ler 0.
O que se pode conhecer da memória
Uma linha WB válida e limpa permite conhecer os bytes correspondentes na memória principal, se nenhum agente externo os alterou. Uma linha válida dirty permite conhecer o valor que o processador lê, mas não o valor antigo na memória. Uma etiqueta diferente ou V=0 não prova nada sobre os dados desse endereço na memória.
Um buffer de escrita pode deixar o CPU continuar enquanto uma escrita WT avança. Se o exercício diz que não existe buffer, cobra a espera por escrita. Se existe, considera a capacidade e as condições de bloqueio fornecidas; não acrescentes sempre a latência inteira ao CPI.
Tempo médio de acesso
O modelo seguinte atende cada pedido antes do seguinte, sem sobrepor faltas. Para um nível, se a penalidade é o tempo adicional depois de verificar a falta:
Com acerto de 1 ns, taxa de falta 5% e penalidade 20 ns, o TMAM é 2 ns. Se os 20 ns já incluíssem a procura inicial, a conta teria de evitar contá-la duas vezes.
De taxas de falta para CPI
Este modelo soma ciclos de espera que não se sobrepõem e não estão já no CPI de base. Caches I e D separadas; uma obtenção de instrução por instrução e fração de instruções com um acesso a dados:
Com base 1,2; ; ; e ambas as penalidades 80 ciclos:
Para uma cache unificada, o número médio de acessos é : . Instruções que realizem vários acessos exigem a sua contagem real. Penalidades dirty podem ser uma parcela adicional, ponderada pela frequência dessas vítimas.
Recuperar a mistura a partir das esperas
A equação também permite obter uma grandeza que não foi medida diretamente. Num CPU de 2 GHz, cada ciclo demora 0,5 ns, por isso uma falta que acrescenta 50 ns custa 100 ciclos.
Suponhamos uma cache unificada com taxa de falta 9% por acesso e 12 ciclos de espera por instrução. Cada instrução faz uma obtenção e, se for load/store, mais um acesso a dados.
Se é a fração de instruções que são loads/stores, com uma obtenção por instrução e no máximo um acesso a dados, as esperas são:
Divide primeiro pela espera média de um acesso:
A obtenção obrigatória explica o primeiro acesso. Subtraí-la dá , ou 33,33% de instruções com acesso a dados. Se fossem caches I/D separadas e os 12 ciclos contassem apenas dados, não haveria esse 1: o denominador e a equação seriam outros.
Neste modelo, . Um resultado fora desse intervalo indica que os dados não cabem nas hipóteses: pode haver várias operações de memória por instrução, ou custos de escrita não incluídos. Também é necessário partir só da parcela de esperas. Usar o CPI total como se toda a execução fosse protelamento mistura grandezas diferentes.
Se a fonte dá uma razão entre acertos e faltas, transforma-a antes de calcular. Acertos nove vezes mais frequentes que faltas significam e , logo . A taxa de falta não é : essa razão tem acertos no denominador.
Vários níveis de cache
Uma falta em L1 consulta L2. Taxa local de L2 é a fração dessas consultas que falha. Taxa global de L2 é a fração de todos os pedidos originais que chega à memória. Se há um pedido por instrução, .
Exemplo: ciclo, , ciclos, , RAM 80 ciclos adicionais. O TMAM é ciclos. A taxa global que chega à RAM é 2%, não 20%.
Para CPI de CPU a 4 GHz, base 1, faltas L1 de 2% por instrução, consulta L2 de 5 ns e faltas RAM globais 0,5% com 100 ns adicionais: ciclos. Logo . Sem L2 seria . A rapidez relativa é , se e a frequência forem iguais.
Tráfego entre níveis com write-back
Uma falta em L1 e uma escrita na RAM são eventos diferentes. Em WB, uma escrita pode falhar para carregar uma linha e só enviar a modificação mais tarde, ao substituir a vítima. Saber a taxa de faltas não basta para contar descargas: é preciso saber quantas vítimas válidas estão dirty e se há flush final.
Segue duas escritas de palavra, E0=7 e E64=9, com estas hipóteses: L1 direta WB/allocate de uma linha de 16 B; L2 direta WT de quatro linhas de 16 B; ambas vazias. Escritas parciais em L1 leem a linha antes de a alterar. Cada descarga de L1 entrega a linha inteira a L2; L2 envia essa escrita inteira à RAM. Não há buffers nem flush final. A memória em ambos os endereços começa a zero.
| Passo | Pedido | Efeito na RAM |
|---|---|---|
| 1 | E0 falha em L1; L1 pede a linha 0 a L2, que também falha | Leitura da linha 0 |
| 2 | L1 modifica a palavra 0 para 7 | Nenhum; L1 fica dirty |
| 3 | E64 falha em L1; a vítima 0 é descarregada para L2 | L2 acerta e, por WT, escreve a linha 0 na RAM |
| 4 | L1 pede a linha 64; L2 falha e substitui a sua linha 0 limpa | Leitura da linha 64 |
| 5 | L1 modifica a palavra 64 para 9 | Nenhum; L1 fica dirty |
São duas leituras e uma escrita de linha na RAM. A descarga da vítima atravessou L2 num acerto, mas gerou escrita porque L2 é WT. A RAM termina com 7 no endereço 0 e ainda 0 no endereço 64; o CPU lê 9 nesse último por acerto em L1. Um flush final acrescentaria outra escrita de linha na RAM, segundo as mesmas regras.
A taxa global conta pedidos de leitura que faltam nos dois níveis, quando cada taxa usa o seu denominador. Não a apliques a todas as escritas WB. Para contar tráfego de escritas, segue separadamente carregamentos, descargas e a alocação de cada nível.
Exercícios
Contar escritas e leituras
Cache WB/allocate direta, 2 linhas de 4 B, vazia. O modelo dispensa ler uma linha que será totalmente escrita e não faz flush final. Palavras completas: E0=7, L0, E8=9, L4, L0. Quantos acessos à memória principal, contando leitura ou escrita de linha como um?
Pista
Solução
E0 não acede à RAM; L0 acerta; E8 descarrega 0; L4 carrega 4; L0 descarrega 8 e carrega 0. Total 4: 2 leituras+2 escritas.
Erros frequentes
Cobrar carga desnecessária para escrita de linha completa ou esquecer o write-back da vítima.
Preservar bytes não escritos
Cache WB com linha 16 B; uma escrita de 4 B falha e escolhe vítima válida dirty. A política lê a linha nova antes de alterar 4 B. Quantas transferências de linha com a memória?
Pista
A vítima deve ser conservada; a linha nova tem bytes não escritos.
Solução
Total 2, porque descarrega 16 B antigos; carrega 16 B novos; altera 4 B na cache e marca dirty.
Erros frequentes
Aplicar a exceção de linha totalmente escrita a uma escrita parcial.
Combinar I e D
Base CPI 1,2; faltas I de 1%, faltas D de 4%; 30% das instruções fazem um acesso a dados; penalidade 80 ciclos. Calcula CPI.
Pista
Solução
CPI=2,96, ou seja, I acrescenta 0,8 e D acrescenta 0,96.
Erros frequentes
Aplicar miss D a todas as instruções ou somar taxas sem os respetivos denominadores.
Usar a taxa local certa
L1 acerto 1 ciclo, miss 10%; L2 consulta 8 ciclos, miss local 20%; RAM 80 ciclos adicionais. Calcula TMAM.
Pista
Solução
Erros frequentes
Cobrar 8 ciclos a todos os pedidos ou tratar 20% local como 20% global.
O que uma linha dirty permite concluir
Cache WB, sem agentes externos nem buffers de escrita. A linha válida do endereço X é dirty e contém X=9. Não sabemos o valor inicial nem houve write-back. O que sabemos sobre uma leitura do CPU e sobre a RAM?
Pista
Distingue a cópia que serve a leitura da cópia no nível seguinte.
Solução
O CPU obtém 9 por acerto. A RAM conserva o valor anterior, que não foi dado. Dirty não permite afirmar que esse valor é diferente de 9, apenas que não há garantia de igualdade.
- O CPU lê 9; o valor atual na RAM é indeterminado.. A linha válida responde ao CPU, mas dirty não revela o valor anterior da RAM.
- O CPU e a RAM têm ambos 9.. WB ainda pode não ter descarregado a modificação.
- O CPU não pode ler porque dirty significa inválida.. Dirty indica modificação, não invalidade.
Erros frequentes
Inventar o valor antigo ou concluir que dirty prova necessariamente uma diferença de valores.
Recuperar acessos a dados a partir das esperas
Um CPU de 2 GHz tem cache unificada com taxa de falta 9% por acesso. Cada falta acrescenta 50 ns, sem sobreposição. Há uma obtenção por instrução e cada load/store faz exatamente um acesso adicional; as outras instruções não acedem a dados. Mediram-se 12 ciclos de espera por instrução, sem contar o CPI de base. Determina a fração de loads/stores. No mesmo modelo, seria possível medir apenas 8 ciclos de espera por instrução?
Pista
Mesmo sem loads/stores, continuam a obter-se instruções.
Solução
Cada ciclo dura 0,5 ns, por isso a penalidade é 50/0,5=100 ciclos. Escreve 12=(1+r)×0,09×100; daí 1+r=4/3 e r=1/3. Mesmo com r=0, a obtenção produz 0,09×100=9 ciclos de espera por instrução. O valor 8 daria r=−1/9 e é incompatível com estas hipóteses. Não é uma fração válida de instruções; seria necessário rever a taxa, a penalidade ou o modelo.
Confere a tua resposta:
- Converti 50 ns para 100 ciclos a 2 GHz.
- Usei 1+r acessos por instrução na cache unificada.
- Obtive r=1/3, isto é, 33,33%.
- Expliquei por que 8 ciclos de espera seriam incompatíveis.
Uma descarga pode chegar à RAM mesmo acertando em L2
E0=7 e E64=9 escrevem palavras de quatro bytes. L1 direta tem uma linha de 16 B, WB/allocate; L2 direta tem quatro linhas de 16 B, WT. Ambas estão vazias e a RAM começa a zero. Uma escrita parcial em L1 carrega antes a linha inteira; a descarga de L1 entrega a linha inteira a L2 e L2 envia-a à RAM, tanto no acerto como na falta. Leituras que falham em L2 carregam a linha. Sem buffers nem flush final, conta as leituras/escritas de linhas da RAM e indica os valores que RAM e CPU têm nos dois endereços. O que mudaria com flush final de L1?
Solução
E0 provoca uma leitura da linha 0 até L1 e deixa aí 7, dirty. E64 expulsa essa linha: L2 ainda a contém, mas a escrita WT atualiza a RAM com 7. Depois carrega a linha 64 da RAM e altera-a para 9 só em L1. Há duas leituras e uma escrita. RAM guarda 7 em 0 e 0 em 64; os valores mais recentes para o CPU são 7 e 9. O último está em L1, mas 0 já não está. Uma leitura posterior de 0 precisaria de o carregar e primeiro descarregaria a vítima 64. O flush final descarrega a linha 64 por L2 e acrescenta uma escrita na RAM, que passa a conter 9. Multiplicar taxas de faltas não contaria a escrita que acertou em L2.
Confere a tua resposta:
- Separei os dois carregamentos da descarga dirty.
- Obtive duas leituras e uma escrita de linha na RAM.
- Mantive 7 na RAM em 0 e 9 apenas na L1 em 64.
- Expliquei por que o flush final acrescentaria outra escrita.