Por que existem caches L1 separados para dados e instruções?


Respostas:


28

Na verdade, existem várias razões.

Primeiro e provavelmente acima de tudo, os dados armazenados no cache de instruções geralmente são um pouco diferentes dos armazenados no cache de dados - junto com as próprias instruções, há anotações para coisas como onde a próxima instrução começa, para ajudar os decodificadores. Alguns processadores (por exemplo, Netburst, alguns SPARCs) usam um "cache de rastreamento", que armazena o resultado da decodificação de uma instrução em vez de armazenar a instrução original em sua forma codificada.

Segundo, simplifica um pouco os circuitos - o cache de dados precisa lidar com leituras e gravações, mas o cache de instruções trata apenas de leituras. (Isso é parte do motivo pelo qual o código de modificação automática é tão caro - em vez de sobrescrever diretamente os dados no cache de instruções, a gravação passa pelo cache de dados para o cache L2 e, em seguida, a linha no cache de instruções é invalidada e re carregado de L2).

Terceiro, aumenta a largura de banda: a maioria dos processadores modernos pode ler dados do cache de instruções e do cache de dados simultaneamente. A maioria também tem filas na "entrada" do cache, para que eles possam realmente fazer duas leituras e uma gravação em qualquer ciclo.

Quarto, ele pode economizar energia. Embora você precise manter a energia das próprias células de memória para manter seu conteúdo, alguns processadores podem / desligam alguns dos circuitos associados (decodificadores e outros) quando não estão sendo usados. Com caches separados, eles podem ligar esses circuitos separadamente para obter instruções e dados, aumentando as chances de um circuito permanecer sem energia durante um determinado ciclo (não tenho certeza se algum processador x86 faz isso - AFAIK, é mais um ARM coisa).


3
Também é importante mencionar que código e dados podem exibir diferentes padrões de acesso; por exemplo, as instruções para somar todos os elementos em uma matriz exibem localidade temporal (as mesmas instruções são usadas com freqüência (se você faz isso por um loop)) e os dados na matriz exibem localidade espacial (os seguintes dados são usados ​​a seguir).
gablin

1
@ gablin: embora verdadeiras, essas diferenças nos padrões geralmente favorecem um cache unificado. Em um loop restrito, como você mencionou, a maior parte do cache de instruções está ociosa. Um cache unificado basicamente dobraria o tamanho do cache de dados pela duração do loop.
Jerry Coffin

Na verdade, não, porque há mais código após esse pequeno loop e também é provável que esteja trabalhando com a matriz. Isso caracteriza uma enorme quantidade de código (por exemplo, manipulação de string). De fato, os primeiros caches das CPUs eram unificados - eles ficavam entre a interface de memória principal da CPU e o barramento externo, que era um local simples para colocá-los - mas agora usamos um cache particionado porque é mais rápido na prática .
Donal Fellows

@Donal Fellows: Sim, realmente. Estou ciente de quão cedo o cache foi feito e por que eles mudaram para um cache dividido.
Jerry Coffin

5

Assim como no setor imobiliário, o uso do cache é impulsionado por três coisas: local, local, local. O ponto principal de ter um cache é que a maioria dos programas exibe padrões de localização: se eles acessam o byte 1111111, o próximo byte a que eles acessam é provavelmente 1111110 ou 1111112, e não o byte 9999999. No entanto, a maioria dos programas exibe muito diferentes. padrões de localização para suas instruções e dados. Isso significa que é improvável que as instruções e os dados possam compartilhar o cache com eficiência. Porque instruções e dados não estão necessariamente próximos um do outro na memória. Um acesso a dados coletaria instruções do cache e as instruções de carregamento coletariam dados do cache.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.