Coerência de cache baseada em diretório - Directory-based cache coherence

Em engenharia da computação , a coerência de cache baseada em diretório é um tipo de mecanismo de coerência de cache , onde os diretórios são usados ​​para gerenciar caches no lugar de métodos de snoopy devido à sua escalabilidade. Os métodos de bus snooping são mal escalonados devido ao uso de transmissão . Esses métodos podem ser usados ​​para atingir o desempenho e a escalabilidade dos sistemas de diretório.

Formato vetorial bit completo

Diagrama do formato de diretório de vetor de bits completo, onde E = Exclusivo, S = Compartilhado, M = Modificado e U = Não armazenado em cache

No formato de vetor de bits completo, para cada linha de cache possível na memória , um bit é usado para rastrear se cada processador individual tem essa linha armazenada em seu cache . O formato do vetor bit completo é a estrutura mais simples de implementar, mas menos escalonável. O SGI Origin 2000 usa uma combinação de vetor de bit completo e vetor de bit grosso, dependendo do número de processadores.

Cada entrada de diretório deve ter 1 bit armazenado por processador por linha de cache, junto com bits para rastrear o estado do diretório. Isso leva a que o tamanho total necessário seja (número de processadores) × número de linhas de cache , tendo uma taxa de sobrecarga de armazenamento de (número de processadores) / (tamanho do bloco de cache × 8) .

Pode-se observar que a sobrecarga do diretório escala linearmente com o número de processadores. Embora isso possa ser adequado para um pequeno número de processadores, quando implementado em sistemas grandes, os requisitos de tamanho para o diretório se tornam excessivos. Por exemplo, com um tamanho de bloco de 32 bytes e 1024 processadores, a taxa de sobrecarga de armazenamento torna-se 1024 / (32 × 8) = 400%.

Formato vetorial de bit grosso

Diagrama do formato de diretório vetorial de bit grosso

O formato de vetor de bit grosso tem uma estrutura semelhante ao formato de vetor de bit completo, embora em vez de rastrear um bit por processador para cada linha de cache, o diretório agrupa vários processadores em nós , armazenando se uma linha de cache está armazenada em um nó em vez de um linha. Isso melhora os requisitos de tamanho em detrimento da economia de tráfego de barramento (processadores por nó) × (linhas totais) bits de espaço. Assim, a sobrecarga de proporção é a mesma, apenas substituindo o número de processadores pelo número de grupos de processadores. Quando uma solicitação de barramento é feita para uma linha de cache que um processador do grupo possui, o diretório transmite o sinal para cada processador no nó, em vez de apenas para os caches que o contêm, levando a tráfego desnecessário para nós que não possuem os dados em cache.

Nesse caso, a entrada do diretório usa 1 bit para um grupo de processadores para cada linha de cache. Para o mesmo exemplo do formato Full Bit Vector, se considerarmos 1 bit para 8 processadores como um grupo, a sobrecarga de armazenamento será 128 / (32 × 8) = 50%. Esta é uma melhoria significativa em relação ao formato Full Bit Vector.

Formato de diretório esparso

Um cache armazena apenas um pequeno subconjunto de blocos na memória principal em um determinado momento. Portanto, a maioria das entradas no diretório pertencerão a blocos não armazenados em cache. No formato de diretório esparso, o desperdício é reduzido, armazenando apenas os blocos em cache no diretório. Considere um processador com tamanho de cache de 64 KB, tamanho de bloco de 32 bytes e tamanho da memória principal de 4 MB. O número máximo de entradas que o diretório pode ter no formato de diretório esparso é 2048. Se o diretório tiver uma entrada para todos os blocos na memória, o número de entradas no diretório será 131072. Assim, é evidente que a melhoria do armazenamento fornecido pelo formato de diretório esparso é muito significativo.

Formato de árvore binária balanceada por número

Nesse formato, o diretório é descentralizado e distribuído entre os caches que compartilham um bloco de memória. Diferentes caches que compartilham um bloco de memória são organizados na forma de uma árvore binária . O cache que acessa primeiro um bloco de memória é o nó raiz . Cada bloco de memória tem as informações do nó raiz (HEAD) e o campo do contador de compartilhamento (SC). O campo SC contém o número de caches que compartilham o bloco. Cada entrada de cache possui ponteiros para os próximos caches de compartilhamento, conhecidos como L-CHD e R-CHD. Uma condição para este diretório é que a árvore binária seja balanceada em número, ou seja, o número de nós na subárvore esquerda deve ser igual ou um maior que o número de nós na subárvore direita. Todas as subárvores também devem ter equilíbrio numérico.

Formato de diretório encadeado

Neste formato, a memória mantém o ponteiro do diretório para o último cache que acessou o bloco e cada cache possui o ponteiro para o cache anterior que acessou o bloco. Portanto, quando um processador envia uma solicitação de gravação a um bloco na memória, ele envia invalidações na cadeia de ponteiros. Neste diretório, quando um bloco de cache é substituído, precisamos percorrer a lista para alterar o diretório que aumenta a latência . Para evitar isso, as listas duplamente vinculadas são amplamente utilizadas agora em que cada cópia em cache possui ponteiros para o cache anterior e o próximo que acessa o bloco.

Formato de ponteiro limitado

O formato de ponteiro limitado usa um número definido de ponteiros para rastrear os processadores que estão armazenando os dados em cache. Quando um novo processador armazena em cache um bloco, um ponteiro livre é escolhido de um pool para apontar para aquele processador. Existem algumas opções para lidar com casos em que o número de compartilhadores excede o número de ponteiros livres. Um método é invalidar um dos compartilhadores, usando seu ponteiro para o novo solicitante, embora isso possa ser caro nos casos em que um bloco tem um grande número de leitores, como um bloqueio. Outro método é ter um pool separado de ponteiros livres disponível para todos os blocos. Este método geralmente é eficaz, pois o número de blocos compartilhados por um grande número de processadores normalmente não é muito grande.

Referências