Esta é uma coleção de micro benchmarks de GPU. Cada teste é projetado para testar um cenário ou mecanismo de hardware específico. Alguns dos benchmarks foram usados para produzir dados para estes artigos:
"Estimativa analítica de desempenho durante a geração de código em GPUs modernas"
"Engenharia de desempenho para núcleos de multiplicação de matrizes altos e finos reais e complexos em GPUs"
Benchmarks chamados gpu-<benchmarkname>
são hipificáveis! Enquanto o alvo Makefile padrão cria o executável CUDA cuda-<benchmarkname>
, o alvo make hip-<benchmarkname>
usa a ferramenta hipify-perl para criar um arquivo main.hip
a partir do arquivo main.cu
e o constrói usando o compilador hip . Os arquivos principais CUDA são escritos para que a ferramenta hipify funcione sem intervenção adicional.
Dê também uma olhada nas funções gpu-metrics, que fornecem uma maneira concisa de medir as métricas do contador de desempenho de hardware de uma inicialização do kernel dentro do programa em execução.
Se algo disso for útil, estrelas e citações são bem-vindas!
Mede a largura de banda dos kernels de streaming para ocupação variável. Uma alocação de memória compartilhada serve como spoiler, de modo que apenas dois blocos de threads podem ser executados por SM. A verificação do tamanho do bloco de threads de 32 a 1024 verifica a ocupação de 3% a 100%.
Núcleo | Fórmula | |
---|---|---|
iniciar | UMA[eu] = c | 1 fluxo de loja |
ler | soma = A[i] | 1 fluxo de carga |
escala | A[i] = B[i] * c | 1 fluxo de carga, 1 fluxo de armazenamento |
tríade | A[i] = B[i] + c * C[i] | 2 fluxos de carga, 1 fluxo de armazenamento |
3 pontos | A[i] = B[i-1] + B[i] + B[i+1] | 1 fluxo de carga, 1 fluxo de armazenamento |
5 pontos | A[i] = B[i-2] + B[i-1] + B[i] + B[i+1] + B[i+2] | 1 fluxo de carga, 1 fluxo de armazenamento |
Resultados de um NVIDIA-H100-PCIe/CUDA 11.7
threads de tamanho de bloco %occ | init tríade de escala de leitura 3pt 5pt 32 3648 3% | GB/s: 228 96 183 254 168 164 64 7296 6,2% | GB/s: 452 189 341 459 316 310 96 10944 9,4% | GB/s: 676 277 472 635 443 436 128 14592 12,5% | GB/s: 888 368 607 821 567 558 160 18240 15,6% | GB/s: 1093 449 704 966 680 670 192 21888 18,8% | GB/s: 1301 533 817 1121 794 781 224 25536 21,9% | GB/s: 1495 612 925 1264 903 889 256 29184 25,0% | GB/s: 1686 702 1037 1399 1005 989 288 32832 28,1% | GB/s: 1832 764 1124 1487 1100 1082 320 36480 31,2% | GB/s: 2015 841 1213 1564 1188 1169 352 40128 34,4% | GB/s: 2016 908 1295 1615 1269 1250 384 43776 37,5% | GB/s: 2016 985 1378 1644 1348 1326 416 47424 40,6% | GB/s: 2016 1045 1439 1641 1415 1395 448 51072 43,8% | GB/s: 2016 1116 1497 1649 1472 1453 480 54720 46,9% | GB/s: 2016 1179 1544 1655 1521 1505 512 58368 50,0% | GB/s: 2017 1261 1583 1675 1556 1545 544 62016 53,1% | GB/s: 2016 1300 1591 1669 1572 1563 576 65664 56,2% | GB/s: 2016 1362 1607 1678 1587 1579 608 69312 59,4% | GB/s: 2018 1416 1619 1689 1598 1592 640 72960 62,5% | GB/s: 2016 1473 1639 1712 1613 1607 672 76608 65,6% | GB/s: 2016 1527 1638 1714 1618 1613 704 80256 68,8% | GB/s: 2015 1578 1644 1725 1625 1619 736 83904 71,9% | GB/s: 2016 1624 1651 1738 1632 1628 768 87552 75,0% | GB/s: 2016 1680 1666 1755 1642 1638 800 91200 78,1% | GB/s: 2015 1714 1663 1758 1645 1642 832 94848 81,2% | GB/s: 2016 1759 1668 1770 1649 1647 864 98496 84,4% | GB/s: 2016 1795 1673 1779 1654 1651 896 102144 87,5% | GB/s: 2016 1837 1686 1796 1663 1662 928 105792 90,6% | GB/s: 2018 1871 1684 1800 1666 1664 960 109440 93,8% | GB/s: 2016 1897 1688 1808 1672 1670 992 113088 96,9% | GB/s: 2016 1919 1693 1818 1678 1675 1024 116736 100,0% | GB/s: 2016 1942 1704 1832 1686 1683
Os resultados para o kernel SCALE e uma seleção de GPUs:
Observe que os resultados do H100 são para a versão PCIe, que possui menor largura de banda DRAM do que a versão SXM!
Referência de busca de ponteiro para medição de latência. Um único warp atravessa totalmente um buffer em ordem aleatória. Um esquema de particionamento é usado para garantir que todas as linhas de cache sejam atingidas exatamente uma vez antes de serem acessadas novamente. A latência nos ciclos de clock é calculada com a taxa de clock atual.
Transições de cache L1 nítidas em 128/192/256 kB para NVIDIAS V100/A100/H100 e em 16kB para MI210 da AMD. V100 e MI210 possuem cache L2 de 6 MB. Os A100 e H100 têm um cache L2 segmentado de 2x20MB e 2x25MB, que se manifesta como um pequeno patamar intermediário quando os dados são obtidos da seção L2 mais distante.
A GPU RDNA2, a RX6900XT, tem a hierarquia de cache mais interessante com seus 4 níveis de cache claramente visíveis: o cache L0 de 16kB, o cache L1 semi-compartilhado de 128kB, o cache L2 de 4MB e o cache Infinity de 128MB. É também a GPU com maior clock, de modo que os tempos de acesso absolutos seriam menores do que as outras GPUs. Medir sua latência de DRAM é difícil, porque a interface DRAM não acelera para uma única frente de onda, resultando em latências de DRAM > 2.000 ciclos.
Mede larguras de banda do primeiro e do segundo nível de cache. Lança um bloco de thread por SM. Cada bloco de thread lê repetidamente o conteúdo do mesmo buffer. A variação dos tamanhos de buffer altera o nível de cache de destino.
As capacidades de cache L1 de 16kB (MI100/MI210), 128kB (V100), 192kB (A100) e 256kB (H100) são muito pronunciadas e nítidas. As três arquiteturas NVIDIA transferem perto de 128B/ciclo/SM, o valor máximo medido no MI100 e MI210 da AMD depende do tipo de dados. Para precisão dupla, o máximo é 32B/ciclo/CU. Para tipos de dados de precisão simples e 16B (float4 ou double2), a largura de banda é de até 64B.
Este benchmark não tem como alvo os níveis de hierarquia de memória além do segundo nível de cache (ou seja, DRAM para a maioria das GPUs), porque os conjuntos de dados não saem claramente de um cache compartilhado. Como todos os blocos de threads leem os mesmos dados, há muito potencial de reutilização dentro do cache compartilhado antes que os dados sejam despejados. Os valores do RX6900XT ultrapassam seu cache L1 compartilhado de 128kB. A100 e H100 caem ligeiramente para 20/25 MB, quando a capacidade de uma única seção de cache é excedida. Além deste ponto, os dados não podem ser replicados em ambas as seções de cache L2 e a largura de banda máxima cai, pois os dados também devem ser buscados na outra seção.
Mede larguras de banda de níveis de cache compartilhado. Este benchmark não visa explicitamente os caches L1.
Todas as três GPUs têm larguras de banda de cache L2 semelhantes de cerca de 5,x TB/s, embora com capacidades diferentes.
Uma observação notável é o RX6900XT, que possui um segundo nível de cache compartilhado, o Infinity Cache de 128 MB. Com quase 1,92 TB/s, é tão rápido quanto a DRAM do A100. Logo no início, o cache L1 semicompartilhado RX6900XT pode ser visto, onde para alguns posicionamentos de bloco os 4 caches L1 têm um pequeno efeito. O mesmo se aplica ao H100, que possui um cache L1 maior com uma chance maior de um bloco de thread encontrar os dados nos quais deseja trabalhar já no cache L1 carregado pelo bloco de thread anterior. Isso funciona apenas para pequenos conjuntos de dados, onde existem apenas alguns blocos de dados diferentes e essa chance ainda é significativa. Isso não é atribuível à Rede de Memória Compartilhada Distribuída, que permite carregar a partir da memória compartilhada de outros SM, porque funciona apenas para cargas explícitas de memória compartilhada e não para cargas globais. Isso exigiria a verificação de tags em cada cache L1 no GPC para qualquer carga.
Somente leitura, benchmark de cache L1 que acessa a memória com passos de 1 a 128. A largura de banda é convertida em bytes por ciclo e SM. Os avanços de 1 a 128 são formatados em um quadro de 16x8, pois isso destaca os padrões recorrentes de múltiplos de 2/4/8/16.
Cada dispositivo recebe um ajuste de
que modela o desempenho com uma sobrecarga de inicialização
Este programa verifica uma variedade de intensidades computacionais, variando a quantidade de disparos do loop interno. É adequado tanto para estudar a transição da memória para códigos vinculados de computação, bem como o consumo de energia, frequências de clock e temperaturas ao usar várias GPUs. O shell script series.sh cria um executável para cada valor e os executa um após o outro após terminar a construção.
O Código é executado simultaneamente em todos os dispositivos disponíveis. Exemplo de saída em quatro Tesla V100 PCIe 16GB:
1 640 blocos 0 seus 0,125 Fl/B 869 GB/s 109 GF/s 1380 Mhz 138 W 60°C2 640 blocos 0 seus 0,125 Fl/B 869 GB/s 109 GF/s 1380 Mhz 137 W 59°C3 640 blocos 0 isso é 0,125 Fl/B 869 GB/s 109 GF/s 1380 Mhz 124 W 56°C0 640 blocos 0 seus 0,125 Fl/B 869 GB/s 109 GF/s 1380 Mhz 124 W 54°C1 640 blocos 8 seus 1,125 Fl/B 861 GB/s 968 GF/s 1380 Mhz 159 W 63°C0 640 blocos 8 seus 1,125 Fl/B 861 GB/s 968 GF/s 1380 Mhz 142 W 56°C2 640 blocos 8 seus 1,125 Fl/B 861 GB/s 968 GF/s 1380 Mhz 157 W 62°C3 640 blocos 8 seus 1,125 Fl/B 861 GB/s 968 GF/s 1380 Mhz 144 W 59°C[...]0 640 blocos 64 seus 8,125 Fl/B 811 GB/s 6587 GF/ s 1380 Mhz 223 W 63°C3 640 blocos 64 seus 8,125 Fl/B 813 GB/s 6604 GF/s 1380 Mhz 230 W 66°C1 640 blocos 64 seus 8,125 Fl/B 812 GB/s 6595 GF/s 1380 Mhz 241 W 71°C2 640 blocos 64 é 8,125 Fl/B 813 GB/s 6603 GF/s 1380 Mhz 243 W 69°C
Mede a taxa de transferência de host para dispositivo da função cudaMemcpy em vários tamanhos de transferência
Exemplo de saída para um Tesla V100 PCIe 16GB
1kB 0,03ms 0,03GB/s 0,68% 2kB 0,03ms 0,06GB/s 5,69% 4kB 0,03ms 0,12GB/s 8,97% 8kB 0,03ms 0,24GB/s 6,25% 16kB 0,04ms 0,44 GB/s 5,16% 32kB 0,04ms 0,93GB/s 2,70% 64kB 0,04ms 1,77GB/s 5,16% 128kB 0,04ms 3,46GB/s 7,55% 256kB 0,05ms 5,27GB/s 1,92% 512kB 0,07ms 7,53GB/s 1,03% 1024kB 0,11ms 9,25GB/s 2,52% 2048kB 0,20ms 10,50GB/s 1,07% 4096kB 0,37ms 11,41GB/s 0,58% 8192kB 0,71ms 11,86GB/s 0,44% 16384kB 1,38ms 12,11GB/s 0,14% 32768kB 2,74ms 12,23GB/s 0,03% 65536kB 5,46ms 12,29 GB/s 0,08% 131072kB 10,89ms 12,32GB/s 0,02% 262144kB 21,75ms 12,34GB/s 0,00% 524288kB 43,47ms 12,35GB/s 0,00% 1048576kB 86,91ms 12,35GB/s 0,00%
Mede a taxa de transferência de memória unificada CUDA usando um kernel de tríade STREAM. Uma variedade de tamanhos de conjuntos de dados é usada, menores e maiores que a memória do dispositivo. Exemplo de saída em um Tesla V100 PCIe 16GB:
tamanho do buffer tempo propagação largura de banda 24 MB 0,1 ms 3,2% 426,2 GB/s 48 MB 0,1 ms 24,2% 511,6 GB/s 96 MB 0,1 ms 0,8% 688,0 GB/s 192 MB 0,3 ms 1,8% 700,0 GB/s 384 MB 0,5 ms 0,5% 764,6 GB/s 768 MB 1,0 ms 0,2% 801,8 GB/s 1536 MB 2,0 ms 0,0% 816,9 GB/s 3072 MB 3,9 ms 0,1% 822,9 GB/s 6144 MB 7,8 ms 0,2% 823,8 GB/s 12288 MB 15,7 ms 0,1% 822,1 GB/s 24576 MB 5108,3 ms 0,5% 5,0 GB/s 49152 MB 10284,7 ms 0,8% 5,0 GB/s
Mede a latência e o rendimento da operação FMA, DIV e SQRT. Ele verifica combinações de ILP = 1..8, gerando 1..8 cadeias de dependência independentes, e TLP, variando a contagem de warp em um SM de 1 a 32. A saída final é uma tabela ILP/TLP, com o recíproco rendimentos (ciclos por operação):
Exemplo de saída em um Tesla V100 PCIe 16GB:
DFMA 8,67 4,63 4,57 4,66 4,63 4,72 4,79 4,97 4,29 2,32 2,29 2,33 2,32 2,36 2,39 2,48 2,14 1,16 1,14 1,17 1,16 1,18 1,20 1,24 1,08 1,05 1,05 1,08 1,08 1,10 1,12 1,14 1,03 1,04 1,04 1,08 1,07 1,10 1,11 1,14 1,03 1,04 1,04 1,08 1,07 1,10 1,10 1,14DDIV111,55 111,53 111,53 111,53 111,53 668,46 779,75 891,05 55,76 55,77 55,76 55,76 55,76 334,26 389,86 445,51 27,88 27,88 27,88 27,88 27,88 167,12 194,96 222,82 14,11 14,11 14,11 14,11 14,11 84,77 98,89 113,00 8,48 8,48 8,48 8,48 8,48 50,89 59,36 67,84 7,51 7,51 7,51 7,51 7,51 44,98 52,48 59,97DSQRT101,26 101,26 101,26 101,26 101,26 612,76 714,79 816,83 50,63 50,62 50,63 50,63 50,62 306,36 357,38 408,40 25,31 25,31 25,31 25,31 25,31 153,18 178,68 204,19 13,56 13,56 13,56 13,56 13,56 82,75 96,83 110,29 9,80 9,80 9,80 9,80 9,80 60,47 70,54 80,62 9,61 9,61 9,61 9,61 9,61 58,91 68,72 78,53
Alguns recursos podem ser extraídos do gráfico.
Latências:
DFMA: 8 ciclos
DDIV: 112 ciclos
DSQRT: 101 ciclos
Taxa de transferência de um warp (executado em um quadrante SM), sem dependências:
DFMA: 1/4 por ciclo (ILP 2, para sobreposição de operações)
DDIV: 1/112 por ciclo (sem ILP/sobreposição)
DSQRT: 1/101 por ciclo (sem ILP/sobreposição)
Taxa de transferência de vários warps (todos os quadrantes SM), dependências irrelevantes:
DFMA: 1 por ciclo
DDIV: 1/7,5 ciclos
DSQRT: 1/9,6 ciclos