Onde está o cache de memória L1 de processadores Intel x86 documentado?
-
23-08-2019 - |
Pergunta
Eu estou tentando perfil e algoritmos de optimização e gostaria de entender o impacto específico das caches em vários processadores. Para recentes processadores Intel x86 (por exemplo, Q9300), é muito difícil encontrar informações detalhadas sobre a estrutura de cache. Em particular, a maioria dos sites (incluindo Intel.com ) que pós-processador especificações não incluem qualquer referência a cache L1. É isto porque o cache L1 não existe ou é esta informação por algum motivo considerados sem importância? Existem quaisquer artigos ou discussões sobre a eliminação do cache L1?
[editar] Depois de executar vários testes e programas de diagnóstico (principalmente daqueles discutidos nas respostas abaixo), cheguei à conclusão de que o meu Q9300 parece ter um cache de dados 32K L1. Eu ainda não encontrei uma explicação clara de por que esta informação é tão difícil de encontrar. A minha teoria de trabalho atual é que os detalhes de L1 cache estão agora a ser tratados como segredos comerciais da Intel.
Solução
É quase impossível encontrar especificações sobre caches Intel. Quando eu estava dando uma aula sobre caches no ano passado, pedi amigos dentro Intel (no grupo do compilador) e que não conseguiu encontrar especificações.
Mas espere !!! Jed , abençoe sua alma, diz-nos que no Linux sistemas, você pode espremer muita informação para fora do núcleo:
grep . /sys/devices/system/cpu/cpu0/cache/index*/*
Isto lhe dará associatividade, tamanho do conjunto, e um monte de outras informações (mas não latência). Por exemplo, eu aprendi que, embora AMD anuncia seu cache 128K L1, minha máquina AMD tem uma divisão I e cache de D de 64K cada um.
Duas sugestões que agora são na sua maioria obsoletos graças a Jed:
-
AMD publica uma muito mais informações sobre os seus caches, para que possa, pelo menos, tem alguma informação sobre um cache moderna. Por exemplo, caches L1 AMD no ano passado entregou duas palavras por ciclo (pico).
-
A ferramenta open-source
valgrind
tem todos os tipos de modelos de cache no seu interior, e é inestimável para perfilar e compreender o comportamento de cache. Ele vem com um muito bomkcachegrind
ferramenta de visualização que faz parte do KDE SDK.
Por exemplo: no Q3 2008, AMD K8 / CPUs K10 utilizar linhas de cache 64 bytes, com um 64kB cada cache separada L1I / L1D. L1D é 2-modo associativo e exclusiva com L2, com latência de 3 ciclos. cache L2 é de 16 vias associativo e latência é de cerca de 12 ciclos.
AMD CPUs Bulldozer familiares usar um L1 dividido com um 16kiB 4-modo associativo L1D por cluster (2 por núcleo).
Intel CPUs têm mantido L1 a mesma por um longo tempo (do Pentium M para Haswell para Skylake e, presumivelmente, muitas gerações depois que): Dividir 32kB cada i e D caches, com L1D sendo 8-way associativo. 64 linhas de cache byte, que correspondem ao tamanho de transferência de explosão de DDR DRAM. Load-uso latência é ~ 4 ciclos.
Também ver a x86 tag wiki para links para mais desempenho e dados da microarquitetura.
Outras dicas
Esta Intel Manual: Intel® 64 e manual de IA-32 arquiteturas de Otimização de Referência tem uma discussão decente de considerações de cache.
Página 46, Seção 2.2.5.1 Intel® 64 e manual de IA-32 arquiteturas de Otimização de Referência
Mesmo MicroSlop está acordando para a necessidade de mais ferramentas para uso de cache do monitor e desempenho, e tem uma GetLogicalProcessorInformation () function exemplo (... enquanto trilha novos caminhos na criação de nomes de função ridiculamente longos no processo) acho que vou codificar-se.
Atualização I: Hazwell aumenta o desempenho da carga de cache 2X, de Dentro de Tock; Arquitetura de Haswell
Se houvesse qualquer dúvida de como é crítico para fazer o melhor uso possível de cache, este apresentação por Cliff Clique, ex-Azul, deve dissipar toda e qualquer dúvida. Em suas palavras, "a memória é o novo disco!".
Atualização II:. Significativamente melhoradas especificações de desempenho cache do Skylake
Você está olhando para as especificações de consumo, e não as especificações do desenvolvedor. Aqui está a documentação que pretende. O cache de tamanhos variam de acordo com sub-modelos da família do processador, para que eles normalmente não estão nos manuais de desenvolvimento IA-32, mas você pode facilmente procurá-los no NewEgg e tal.
Editar: Mais especificamente: Capítulo 10 de 3A Volume (Sistemas Guia de Programação), o Capítulo 7 da Otimização Manual de Referência e, potencialmente, algo no TLB página-cache manual, embora eu diria que um é mais longe do L1 do que você gosta.
Eu fiz um pouco mais de investigação. Há um grupo na ETH Zurique que construiu um ferramenta de avaliação de memória de desempenho que pode ser capaz de obter informações sobre o tamanho, pelo menos (e talvez também associatividade) de caches L1 e L2. O programa funciona por tentar diferentes padrões de leitura experimentalmente e medir o rendimento resultante. Uma versão simplificada foi utilizado para a livro popular por Bryant e O'Hallaron .
existem caches L1 nessas plataformas. Isso quase certamente vou permanecer fiel até a memória e velocidades de barramento frontal exceder a velocidade da CPU, o que é muito provável um longo caminho.
No Windows, você pode usar o GetLogicalProcessorInformation para obter algum nível de informação cache (tamanho, tamanho da linha, associatividade, etc.) A versão Ex em Win7 vai dar ainda mais dados, como que núcleos share que cache. CPUZ também dá esta informação.
localidade de referência tem um grande impacto sobre o desempenho de alguns algoritmos; O tamanho ea velocidade da L1, L2 (e no mais recente CPUs L3) cache, obviamente, desempenham um papel importante neste processo. A multiplicação de matrizes é um tal algoritmo.
Intel Vol Manual. 2 especifica a seguinte fórmula para o tamanho do cache de computação:
Este tamanho de cache em Bytes
= (Ways + 1) * (partições + 1) * (Line_Size + 1) * (Sets + 1)
= (EBX [31:22] + 1) * (EBX [21:12] + 1) * (EBX [11: 0] + 1) * (ECX + 1)
Quando o Ways
, Partitions
, Line_Size
e Sets
são consultados usando cpuid
com o conjunto eax
para 0x04
.
O fornecimento da declaração de arquivo de cabeçalho
x86_cache_size.h
:
unsigned int get_cache_line_size(unsigned int cache_level);
Os olhares de implementação da seguinte forma:
;1st argument - the cache level
get_cache_line_size:
push rbx
;set line number argument to be used with CPUID instruction
mov ecx, edi
;set cpuid initial value
mov eax, 0x04
cpuid
;cache line size
mov eax, ebx
and eax, 0x7ff
inc eax
;partitions
shr ebx, 12
mov edx, ebx
and edx, 0x1ff
inc edx
mul edx
;ways of associativity
shr ebx, 10
mov edx, ebx
and edx, 0x1ff
inc edx
mul edx
;number of sets
inc ecx
mul ecx
pop rbx
ret
O que na minha máquina funciona da seguinte maneira:
#include "x86_cache_size.h"
int main(void){
unsigned int L1_cache_size = get_cache_line_size(1);
unsigned int L2_cache_size = get_cache_line_size(2);
unsigned int L3_cache_size = get_cache_line_size(3);
//L1 size = 32768, L2 size = 262144, L3 size = 8388608
printf("L1 size = %u, L2 size = %u, L3 size = %u\n", L1_cache_size, L2_cache_size, L3_cache_size);
}