Tenho uma placa-mãe Asus WS-Pro-X570-ACE e conecto dois pentes de memória exatamente iguais (Hynix, 16 GB, DDR4, 2R*8) nos slots A2 e B2, de acordo com o manual do usuário sobre Habilitar Canal Duplo, seção 1.4 (página 1-12).
Mas quando executo sysbench memory run
no debian12, obtenho um resultado que é o mesmo que quando executo no modo de canal único.
Assim:
sysbench 1.0.20 (usando o sistema LuaJIT 2.1.0-beta3)
Executando o teste com as seguintes opções: Número de threads: 1 Inicializando o gerador de números aleatórios a partir do horário atual
Executando teste de velocidade de memória com as seguintes opções: tamanho do bloco: 1 KiB tamanho total: 102400 MiB operação: gravação escopo: global
Inicializando threads de trabalho...
Tópicos iniciados!
Total de operações: 77184144 (7718000,79 por segundo)
75375,14 MiB transferidos (7537,11 MiB/seg)
Estatísticas gerais: tempo total: 10.0000s número total de eventos: 77184144
Latência (ms): min: 0,00 avg: 0,00 max: 0,01 95º percentil: 0,00 soma: 3647,56
Justiça de threads: eventos (média/desvio padrão): 77184144,0000/0,00 tempo de execução (média/desvio padrão): 3,6476/0,00
Existe algum método complicado que eu tenha esquecido?
Um sistema DDR4 de 2 canais @ 3200 MT/s tem uma largura de banda de memória de pico teórica de 64b x 2 x 3,2G / 8 = 51,2 GB/s, mas seu benchmark mostra apenas 7,5 GB/s, o que é 10% do valor de pico teórico. Portanto, o benchmark em si é falho. Você não está saturando sua largura de banda de memória de sistema de pico para começar, então a falta de diferença não é surpreendente.
Um bom benchmark de memória deve ser multithread, já que um aplicativo single-thread geralmente é incapaz de saturar a largura de banda completa (a vetorização pode ajudar, mas apenas até certo ponto). Além disso, o loop interno do programa deve ser idealmente escrito em uma linguagem de baixo nível como assembly, ou FORTRAN/C com otimização do compilador, para que você possa colocar o maior estresse na CPU e seu subsistema de memória. Existem vários benchmarks de memória respeitáveis e padrão da indústria disponíveis, incluindo o benchmark STREAM de John D. McCalpin e o benchmark de memória integrado incluído na ferramenta
likwid-bench
no LIKWID. Ambas as ferramentas são amplamente utilizadas no mundo da computação científica e de alto desempenho e foram usadas em muitos artigos de pesquisa acadêmica.Portanto, considere usar STREAM ou
likwid-bench
medir corretamente a largura de banda de memória do seu sistema.FLUXO
STREAM é um pequeno código C/FORTRAN escrito pelo Dr. John D. McCalpin e tem sido usado em supercomputadores de referência desde a década de 1990. Hoje, continua sendo um padrão da indústria devido à sua simplicidade.
Para executar um teste STREAM, obtenha o código-fonte em https://github.com/jeffhammond/STREAM (este é um espelho não oficial).
Compile o código C manualmente (não use o
Makefile
) com:A macro
STREAM_ARRAY_SIZE
controla o tamanho do array alocado.Em seguida, execute-o com:
Por padrão, o OpenMP executará STREAM em todos os núcleos da CPU. Finalmente, o seguinte resultado pode ser obtido:
Devido à falta de otimização de armazenamento não temporal no GCC, nos testes Scale, Add e Triad, a CPU executa Write-Allocate, o que cria uma sobrecarga extra no subsistema de memória que não é medida. Para interpretar corretamente esse resultado, você deve multiplicar o resultado de Scale por 1,5 e multiplicar o resultado de Add e Triad por 1,33. O motivo para fazer isso envolve uma compreensão do cache da CPU, já expliquei em outra resposta Resultados esperados de um benchmark de largura de banda de memória de fluxo aqui.
Por exemplo, neste caso:
Como você pode ver, na minha máquina, estou obtendo cerca de 40 GB/s de largura de banda de memória no benchmark STREAM em todos esses testes. Isso é esperado, pois a largura de banda de memória utilizável geralmente fica em torno de 70%-80% da largura de banda teórica da memória. Observe que a largura de banda de memória é sempre relatada em GB/s por convenção, não em GiB/s.
Executar a memória de canal único do sistema reduzirá pela metade a velocidade do STREAM. Tente fazer este experimento você mesmo: Remova um canal DIMM, os resultados do STREAM serão reduzidos em 50. Adicione o canal DIMM de volta, os resultados sobem novamente.
LÍQUIDO
STREAM é um clássico, então é útil executá-lo para comparação com benchmarks de outras pessoas. Mas ele pode ser propenso a erros. Em desktops, pode ser aceitável (desde que você entenda a eficácia dos Non-Temporal Stores). Mas em servidores, há muitas armadilhas relacionadas ao comportamento de alocação de gravação do NUMA, compilador e CPU - que não são manipuladas automaticamente e podem gerar resultados enganosos.
Então, para testar a largura de banda da memória da CPU, prefiro usar o LIKWID. O Likwid é o canivete suíço do ajuste de desempenho em aplicativos HPC. Seu uso principal é coletar estatísticas de contadores de desempenho de hardware de baixo nível para entender e otimizar as características de desempenho do seu código. Mas ele também inclui uma ferramenta micro-benchmacrk chamada
likwid-bench
.Primeiro, execute
make
emake install
de acordo com o manual oficial do LIKWID. Então, uma ferramenta chamadalikwid-bench
se torna disponível.likwid-bench
pode iniciar automaticamente várias instâncias dos programas de benchmark e fixar o processo e a memória de cada instância em seu nó NUMA correspondente. Ele também fornece muitos kernels de benchmark pré-escritos (incluindo o equivalente a um benchmark STREAM Triad) em assembly escrito à mão, permitindo resultados precisos e consistentes, como:Aqui está um exemplo de uso
likwid-bench
para medir a largura de banda da memória usando o benchmark STREAM Triad, usando AVX, FMA e armazenamentos não temporais, usando 4 instâncias, cada uma fixada de forma ideal a um nó NUMA.Para comparar um único computador desktop usando o teste STREAM Triad, execute:
O argumento
M0:1GB
significa executar o teste no primeiro nó NUMA da máquina. Como os computadores desktop têm apenas um nó NUMA, isso é adequado. Para servidores, use tantos nós NUMA quantos a CPU tiver.Como o código assembly já usa armazenamentos não temporais para otimização, não há necessidade de corrigir manualmente o
likwid-bench
resultado. Olikwid-bench
resultado deve ser muito similar ao resultado STREAM corrigido manualmente.Para referência, esta é uma máquina Intel Xeon E5-2680 v4 de soquete duplo com DDR4 ECC RDIMM de 4 canais a 2400 MT/s em cada soquete, então ela deve se comportar como uma máquina de 8 canais. O modo Cluster-On-Die é habilitado no BIOS, como resultado, cada CPU é vista como dois nós NUMA - o silício da CPU é fisicamente particionado em 2 partes, cada uma com seu próprio controlador de memória de 2 canais interconectado por pontes entre dois Ring Bus separados, cada um com metade dos núcleos. A máquina inteira tem 4 nós NUMA. Para aplicativos com reconhecimento de NUMA, isso oferece a maior largura de banda de memória.
Aumentar o número de threads em
sysbench
?Não estou familiarizado com
sysbench
, mas ele permite que você execute o benchmark de memória com múltiplos threads. Se sim, considere refazer seu próprio teste usando tantos threads quanto núcleos de CPU ou threads SMT de hardware.