Aqui está uma captura de tela de uma referência de cache:
No benchmark, a velocidade de leitura do cache L1 é de cerca de 186 GB / s, com a latência sendo de cerca de 3-4 ciclos de clock. Como essa velocidade é alcançada?
Considere a memória aqui: a velocidade máxima teórica é 665 MHz (frequência de memória) x 2 (taxa de dados dupla) x 64 bits (largura do barramento) que é de cerca de 10,6 GB / s, mais próxima do valor de referência de 9,6 GB / s .
Mas, com o cache L1, mesmo que pudéssemos ler a cada ciclo com o processador em sua frequência máxima (3 GHz), precisaríamos de 496 linhas de dados para obter uma taxa de transferência que parece irreal. Isso se aplica a outros caches também.
o que estou perdendo? Como calculamos a taxa de transferência de um cache a partir de seus parâmetros?
fonte
Respostas:
Esta CPU possui ...
Como existem dois núcleos, podemos esperar que o benchmark execute dois threads em paralelo. No entanto, o site deles fornece poucas informações, mas se olharmos aqui , as CPUs com mais núcleos parecem fornecer taxas de transferência L1 correspondentemente mais altas. Então, acho que o que é exibido é uma taxa de transferência total com todos os núcleos trabalhando em paralelo. Portanto, para sua CPU, devemos dividir por dois para um núcleo e um cache:
Agora, o fato de "copiar" é 2x mais rápido que "gravar" é altamente suspeito. Como ele pode copiar mais rápido do que pode escrever? Aposto que o que o benchmark exibe como "cópia" é a soma da taxa de transferência de leitura + gravação e, nesse caso, ele lê e escreve a 45 GB / s, mas exibe 90, porque é um benchmark, e quem diabos confia nos benchmarks? Então, vamos ignorar "copiar".
Agora, um registro de 128 bits tem 16 bytes, perto o suficiente, então parece que esse cache pode fazer duas leituras de 128 bits e uma gravação por relógio.
É exatamente isso que você deseja otimizar realmente essas instruções de processamento de números do SSE: duas leituras e uma gravação por ciclo.
Isso provavelmente seria implementado com muitas linhas de dados paralelas, que é a maneira usual de transportar muitos dados muito rapidamente dentro de um chip.
fonte
a[i] = b[i] + c[i]
). BTW, Intel Haswell e mais tarde têm uma AGU de loja na porta 7 que pode lidar com modos de endereçamento simples (não indexados), para que eles possam executar 2 carregamentos + 1 armazenamento de armazenamento por relógio. (E o caminho de dados para o L1D é 256b, portanto, dobra a largura de banda do L1D.) Veja o artigo de David Kanter: realworldtech.com/haswell-cpu/5A resposta da @ peufeu indica que essas são larguras de banda agregadas em todo o sistema. L1 e L2 são caches privados por núcleo na família Intel Sandybridge, portanto, os números são 2x o que um único núcleo pode fazer. Mas isso ainda nos deixa com uma largura de banda impressionantemente alta e baixa latência.
O cache L1D está embutido no núcleo da CPU e está muito acoplado às unidades de execução de carga (e ao buffer de armazenamento) . Da mesma forma, o cache L1I fica ao lado da parte de busca / decodificação de instruções do núcleo. (Na verdade, eu não olhei para uma planta baixa de silício Sandybridge, então isso pode não ser literalmente verdade. A parte de edição / renomeação do front-end provavelmente está mais próxima do cache de UOP decodificado "L0", que economiza energia e tem melhor largura de banda do que os decodificadores.)
Por que parar aí? A Intel, desde Sandybridge, e a AMD, desde o K8, podem executar 2 cargas por ciclo. Caches de várias portas e TLBs são uma coisa.
A descrição da microarquitetura Sandybridge de David Kanter tem um belo diagrama (que também se aplica à sua CPU IvyBridge):
(O "planejador unificado" mantém ALU e uops de memória aguardando que suas entradas estejam prontas e / ou aguardando sua porta de execução. (Por exemplo,
vmovdqa ymm0, [rdi]
decodifica para um uop de carregamento que precisa aguardarrdi
se um anterioradd rdi,32
ainda não tiver sido executado, por A Intel agenda agendamentos para portas no momento da emissão / renomeação . Este diagrama mostra apenas as portas de execução para entradas de memória, mas as UU ALU não executadas também competem por ela. O estágio de edição / renomeação adiciona entradas para o ROB e o planejador Eles permanecem no ROB até a aposentadoria, mas no planejador somente até o envio para uma porta de execução (esta é a terminologia da Intel; outras pessoas usam o problema e o despacho de maneira diferente). A AMD usa planejadores separados para números inteiros / FP, mas os modos de endereçamento sempre usam registros inteirosComo isso mostra, existem apenas duas portas AGU (unidades de geração de endereços, que assumem um modo de endereçamento
[rdi + rdx*4 + 1024]
e produzem um endereço linear). Pode executar 2 operações de memória por relógio (de 128b / 16 bytes cada), sendo que uma delas é uma loja.Mas ele tem um truque na manga: o SnB / IvB executa 256b AVX carrega / armazena como um único uop que leva 2 ciclos em uma porta de carregamento / armazenamento, mas só precisa da AGU no primeiro ciclo. Isso permite que um uop de endereço de loja seja executado no AGU na porta 2/3 durante o segundo ciclo sem perder nenhuma taxa de transferência de carga. Portanto, com o AVX (que os processadores Intel Pentium / Celeron não suportam: /), o SnB / IvB pode (em teoria) suportar 2 cargas e 1 armazenamento por ciclo.
Sua CPU IvyBridge é o encolhimento da Sandybridge (com algumas melhorias microarquiteturais, como eliminação de mov , ERMSB (memcpy / memset) e pré-busca de hardware da próxima página). A geração seguinte (Haswell) dobrou a largura de banda L1D por relógio, ampliando os caminhos de dados das unidades de execução para L1 de 128b para 256b, para que as cargas do AVX 256b possam sustentar 2 por relógio. Ele também adicionou uma porta AGU de armazenamento extra para modos de endereçamento simples.
A taxa de transferência de pico da Haswell / Skylake é de 96 bytes carregados + armazenados por relógio, mas o manual de otimização da Intel sugere que a taxa de transferência média sustentada da Skylake (ainda assumindo que não haja perdas de L1D ou TLB) é de ~ 81B por ciclo. (Um loop inteiro escalar pode suportar 2 cargas + 1 armazenamento por relógio, de acordo com meu teste no SKL, executando 7 uops (domínio não fundido) por relógio de 4 uops de domínio fundido. Mas diminui um pouco com operandos de 64 bits em vez de 32 bits, aparentemente, há algum limite de recursos microarquiteturais e não se trata apenas de agendar Uops de endereço de loja para a porta 2/3 e roubar ciclos de cargas.)
Você não pode, a menos que os parâmetros incluam números de rendimento práticos. Como observado acima, mesmo o L1D da Skylake não consegue acompanhar suas unidades de execução de carregamento / armazenamento para vetores 256b. Embora seja próximo, e pode ser para números inteiros de 32 bits. (Não faria sentido ter mais unidades de carga do que o cache tinha portas de leitura ou vice-versa. Você deixaria de fora o hardware que nunca poderia ser totalmente utilizado. Observe que o L1D pode ter portas extras para enviar / receber linhas para / de outros núcleos, bem como para leituras / gravações de dentro do núcleo.)
Só de olhar para as larguras e relógios do barramento de dados, não dá toda a história. As larguras de banda L2 e L3 (e memória) podem ser limitadas pelo número de erros pendentes que L1 ou L2 podem rastrear . A largura de banda não pode exceder a latência * max_concurrency, e os chips com maior latência L3 (como um Xeon com muitos núcleos) têm muito menos largura de banda L3 com um único núcleo do que uma CPU dual / quad core da mesma microarquitetura. Consulte a seção "plataformas ligadas à latência" desta resposta do SO . As CPUs da família Sandybridge têm 10 buffers de preenchimento de linha para rastrear as falhas L1D (também usadas pelas lojas do NT).
(A largura de banda agregada de L3 / memória com muitos núcleos ativos é enorme em um grande Xeon, mas o código de thread único vê uma largura de banda pior do que em um quad core na mesma velocidade de clock, porque mais núcleos significam mais paradas no barramento em anel e, portanto, maior latência L3.)
Latência do cache
A latência de uso de carga de 4 ciclos do cache L1D é bastante surpreendente , especialmente considerando que ele precisa começar com um modo de endereçamento
[rsi + 32]
, portanto, é necessário adicionar um antes que ele tenha um endereço virtual . Em seguida, é necessário traduzir isso para físico para verificar as tags de cache para uma correspondência.(Outros modos de endereçamento além de
[base + 0-2047]
dar um ciclo extra na família Intel Sandybridge, portanto, há um atalho nas AGUs para modos simples de endereçamento (típico para casos de busca de ponteiros em que baixa latência de uso de carga é provavelmente mais importante, mas também comum em geral) (Consulte o manual de otimização da Intel , seção Sandybridge 2.3.5.2 L1 DCache.) Isso também pressupõe nenhuma substituição de segmento e um endereço base de segmento0
, o que é normal.)Ele também precisa investigar o buffer de armazenamento para verificar se ele se sobrepõe a outros armazenamentos anteriores. E isso deve ser resolvido mesmo que um uop de endereço de loja anterior (em ordem de programa) ainda não tenha sido executado, portanto, o endereço de loja não é conhecido. Mas, presumivelmente, isso pode acontecer em paralelo com a verificação de um acerto L1D. Se os dados L1D não forem necessários, porque o encaminhamento de loja pode fornecer os dados do buffer de armazenamento, isso não significa perda.
A Intel usa caches VIPT (virtualmente indexados fisicamente), como quase todo mundo, usando o truque padrão de ter o cache pequeno o suficiente e com associatividade alta o suficiente para se comportar como um cache PIPT (sem alias) com a velocidade do VIPT (pode indexar em paralelo com a pesquisa virtual-> física do TLB).
Os caches L1 da Intel são associativos de 32 kB e 8 vias. O tamanho da página é 4kiB. Isso significa que os bits de "índice" (que selecionam qual conjunto de 8 maneiras pode armazenar em cache qualquer linha) estão todos abaixo do deslocamento da página; ou seja, esses bits de endereço são deslocados em uma página e são sempre os mesmos no endereço virtual e físico.
Para obter mais detalhes sobre isso e outros detalhes sobre por que caches pequenos / rápidos são úteis / possíveis (e funcionam bem quando combinados com caches maiores e mais lentos), veja minha resposta sobre por que o L1D é menor / mais rápido que o L2 .
Caches pequenos podem fazer coisas que seriam muito caras em caches maiores, como buscar as matrizes de dados de um conjunto ao mesmo tempo que buscar tags. Portanto, uma vez que um comparador encontre qual tag corresponde, ele precisa compactar uma das oito linhas de cache de 64 bytes que já foram buscadas na SRAM.
(Na verdade, não é tão simples assim: o Sandybridge / Ivybridge usa um cache L1D com banco, com oito bancos de blocos de 16 bytes. Você pode obter conflitos entre bancos de cache se dois acessos ao mesmo banco em diferentes linhas de cache tentarem executar no mesmo ciclo. (Existem 8 bancos, portanto, isso pode acontecer com endereços com um múltiplo de 128, ou seja, 2 linhas de cache.)
O IvyBridge também não possui penalidade pelo acesso não alinhado, desde que não ultrapasse o limite da linha de cache de 64B. Acho que descobre quais bancos buscar com base nos bits de endereço baixos e configura qualquer mudança necessária para obter os 1 a 16 bytes de dados corretos.
Em divisões de linha de cache, ainda é apenas um uop, mas faz vários acessos ao cache. A penalidade ainda é pequena, exceto em 4k-splits. O Skylake torna as divisões de até 4k razoavelmente baratas, com latência de cerca de 11 ciclos, o mesmo que uma divisão de linha de cache normal com um modo de endereçamento complexo. Porém, a taxa de transferência dividida em 4k é significativamente pior que a divisão não dividida.
Fontes :
fonte
Nas CPUs modernas, a memória cache fica ao lado da CPU na mesma matriz (chip) , é feita usando SRAM, que é muito, muito mais rápida que a DRAM usada para os módulos de RAM em um PC.
Por unidade de memória (um bit ou byte), a SRAM é muito mais cara que a DRAM. É por isso que a DRAM também é usada em um PC.
Mas como a SRAM é fabricada com a mesma tecnologia que a própria CPU, ela é tão rápida quanto a CPU. Além disso, há apenas barramentos internos (na CPU) para lidar; portanto, se precisar ser um barramento de 496 linhas de largura, provavelmente é.
fonte
Os caches L1 são estruturas de memória bastante amplas. A arquitetura dos caches L1 nos processadores Intel pode ser encontrada neste manual (fornecido pelo next-hack). No entanto, a interpretação de alguns parâmetros está incorreta, o "tamanho da linha de cache" não é a "largura dos dados", é o tamanho do bloco serial de acesso a dados atômicos.
A Tabela 2-17 (seção 2.3.5.1) indica que, nas cargas (leituras), a largura de banda do cache é de 2x16 = 32 bytes por núcleo por CYCLE . Isso por si só fornece largura de banda teórica de 96 Gb / s em um núcleo de 3GHz. Não está claro o que o benchmark citado relata, parece que ele mede dois núcleos trabalhando em paralelo, por isso gera 192 Gbps para dois núcleos.
fonte
Atrasos no portão são o que? 10 picossegundos? O tempo de ciclo para operações inteiras em pipeline é de 333 picossegundos, com várias atividades de decodificação e barramento e captura de dados em flip-flop antes do início do próximo ciclo de clock.
Espero que a atividade mais lenta na leitura de um cache esteja aguardando que os datalines se afastem o suficiente (provavelmente estes são diferenciais: uma referência e uma cobrança real do bit de leitura) para que um comparador / trava possa ser cronometrado para implementar um ação de feedback para converter uma pequena tensão em um grande balanço de tensão no nível lógico trilho a trilho (cerca de 1 volt).
fonte
[reg + 0-2047]
), uma pesquisa TLB e uma comparação de tags (associativa de 8 vias) e a colocação dos 16 bytes desalinhados resultantes no porta de saída da unidade de carga, para encaminhamento para outras unidades de execução. É latência 4c para um loop de perseguição de ponteiromov rax, [rax]
.