Dies ist eine Sammlung von GPU-Mikro-Benchmarks. Jeder Test dient dazu, ein bestimmtes Szenario oder einen Hardwaremechanismus zu testen. Einige der Benchmarks wurden verwendet, um Daten für diese Arbeiten zu erstellen:
„Analytische Leistungsschätzung bei der Codegenerierung auf modernen GPUs“
„Performance-Engineering für echte und komplexe Tall-&-Skinny-Matrix-Multiplikationskerne auf GPUs“
Benchmarks, die gpu-<benchmarkname>
heißen, sind hipifizierbar! Während das Standard-Makefile-Ziel die ausführbare CUDA-Datei cuda-<benchmarkname>
erstellt, verwendet das Ziel make hip-<benchmarkname>
das Tool hipify-perl, um eine Datei main.hip
aus der Datei main.cu
zu erstellen, und erstellt sie mit dem Hip-Compiler . Die CUDA-Hauptdateien sind so geschrieben, dass das Hipify-Tool ohne weiteren Eingriff funktioniert.
Werfen Sie auch einen Blick auf die GPU-Metrik-Funktionen, die eine präzise Möglichkeit zur Messung der Hardware-Leistungsindikatormetriken eines Kernel-Starts innerhalb des laufenden Programms bieten.
Wenn irgendetwas davon nützlich ist, sind Sterne und Zitate willkommen!
Misst die Bandbreite von Streaming-Kerneln bei unterschiedlicher Auslastung. Als Spoiler dient eine Shared-Memory-Allokation, sodass pro SM nur zwei Thread-Blöcke laufen können. Beim Scannen der Thread-Blockgröße von 32 bis 1024 wird die Belegung von 3 % bis 100 % gescannt.
Kernel | Formel | |
---|---|---|
init | A[i] = c | 1 Store-Stream |
lesen | Summe = A[i] | 1 Ladestrom |
Skala | A[i] = B[i] * c | 1 Ladestream, 1 Speicherstream |
Dreiklang | A[i] = B[i] + c * C[i] | 2 Ladeströme, 1 Speicherstrom |
3pt | A[i] = B[i-1] + B[i] + B[i+1] | 1 Ladestream, 1 Speicherstream |
5pt | A[i] = B[i-2] + B[i-1] + B[i] + B[i+1] + B[i+2] | 1 Ladestream, 1 Speicherstream |
Ergebnisse einer NVIDIA-H100-PCIe / CUDA 11.7
blockSize-Threads %occ | init read Scale Triad 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
Die Ergebnisse für den SCALE-Kernel und eine Auswahl an GPUs:
Beachten Sie, dass die H100-Ergebnisse für die PCIe-Version gelten, die über eine geringere DRAM-Bandbreite als die SXM-Version verfügt!
Pointer-Chasing-Benchmark zur Latenzmessung. Ein einzelner Warp durchläuft einen Puffer vollständig in zufälliger Reihenfolge. Mithilfe eines Partitionierungsschemas wird sichergestellt, dass alle Cache-Zeilen genau einmal getroffen werden, bevor erneut auf sie zugegriffen wird. Die Latenz in Taktzyklen wird mit der aktuellen Taktrate berechnet.
Scharfe L1-Cache-Übergänge bei 128/192/256 kB für NVIDIAS V100/A100/H100 und bei 16 kB für AMDs MI210. V100 und MI210 verfügen beide über einen 6 MB großen L2-Cache. Die A100 und H100 verfügen über einen segmentierten L2-Cache mit 2 x 20 MB und 2 x 25 MB, der sich als kleines Zwischenplateau manifestiert, wenn Daten aus dem entfernten L2-Abschnitt abgerufen werden.
Die RDNA2-GPU, die RX6900XT, verfügt über die interessanteste Cache-Hierarchie, wobei ihre 4 Cache-Ebenen deutlich sichtbar sind: der 16-kB-L0-Cache, der 128-kB-Semi-Shared-L1-Cache, der 4-MB-L2-Cache und der 128-MB-Infinity-Cache. Außerdem handelt es sich um die am höchsten taktende GPU, sodass die absoluten Zugriffszeiten geringer wären als bei den anderen GPUs. Die Messung der DRAM-Latenz ist schwierig, da die DRAM-Schnittstelle nicht für eine einzelne Wellenfront hochtaktet, was zu DRAM-Latenzen von > 2000 Zyklen führt.
Misst Bandbreiten der ersten und zweiten Cache-Ebene. Startet einen Thread-Block pro SM. Jeder Thread-Block liest wiederholt den Inhalt desselben Puffers. Unterschiedliche Puffergrößen ändern die angestrebte Cache-Ebene.
Die L1-Cache-Kapazitäten von 16 kB (MI100/MI210), 128 kB (V100), 192 kB (A100) und 256 kB (H100) sind sehr ausgeprägt und scharf. Die drei NVIDIA-Architekturen übertragen beide nahezu 128B/Zyklus/SM, der maximale gemessene Wert bei AMDs MI100 und MI210 hängt vom Datentyp ab. Für doppelte Genauigkeit beträgt das Maximum 32B/Zyklus/CU. Für Datentypen mit einfacher Genauigkeit und 16B (entweder float4 oder double2) beträgt die Bandbreite bis zu 64B.
Dieser Benchmark zielt nicht auf die Speicherhierarchieebenen ab der zweiten Cache-Ebene ab (d. h. DRAM für die meisten GPUs), da die Datensätze nicht eindeutig aus einem gemeinsam genutzten Cache herausfallen. Da alle Thread-Blöcke dieselben Daten lesen, besteht im gemeinsam genutzten Cache viel Wiederverwendungspotenzial, bevor die Daten entfernt werden. Die Werte des RX6900XT liegen um Längen über dem 128 KB großen gemeinsam genutzten L1-Cache. A100 und H100 sinken bei 20/25 MB leicht, wenn die Kapazität eines einzelnen Cache-Abschnitts überschritten wird. Ab diesem Punkt können Daten nicht mehr in beiden L2-Cache-Abschnitten repliziert werden und die maximale Bandbreite sinkt, da Daten auch aus dem anderen Abschnitt abgerufen werden müssen.
Misst Bandbreiten gemeinsam genutzter Cache-Ebenen. Dieser Benchmark zielt ausdrücklich nicht auf die L1-Caches ab.
Alle drei GPUs haben ähnliche L2-Cache-Bandbreiten von etwa 5,x TB/s, allerdings mit unterschiedlichen Kapazitäten.
Eine bemerkenswerte Beobachtung ist der RX6900XT, der über eine zweite gemeinsame Cache-Ebene verfügt, den 128 MB Infinity Cache. Mit knapp 1,92 TB/s ist es genauso schnell wie der DRAM des A100. Ganz am Anfang ist der semi-shared L1-Cache des RX6900XT zu sehen, wobei bei einigen Blockplatzierungen die 4 L1-Caches einen kleinen Effekt haben. Dasselbe gilt für den H100, der über einen größeren L1-Cache verfügt und eine erhöhte Chance für einen Thread-Block bietet, die Daten, an denen er arbeiten möchte, bereits im L1-Cache zu finden, der vom vorherigen Thread-Block geladen wurde. Dies funktioniert nur bei kleinen Datensätzen, bei denen es nur wenige unterschiedliche Datenblöcke gibt und diese Chance immer noch erheblich ist. Dies ist nicht auf das Distributed Shared Memory Network zurückzuführen, das das Laden aus dem gemeinsam genutzten Speicher anderer SM ermöglicht, da es nur für explizite gemeinsam genutzte Speicherlasten und nicht für globale Lasten funktioniert. Dies würde eine Tag-Überprüfung jedes L1-Cache im GPC auf jede Auslastung erfordern.
Nur lesen, L1-Cache-Benchmark, der mit Schritten von 1 bis 128 auf den Speicher zugreift. Die Bandbreite wird in Bytes pro Zyklus und SM konvertiert. Die Schritte von 1 bis 128 werden in einem 16x8-Tableau formatiert, da dadurch die wiederkehrenden Muster der Vielfachen von 2/4/8/16 hervorgehoben werden.
Jedes Gerät erhält einen Anfall von
welches die Leistung mit einem Startup-Overhead modelliert
Dieses Programm scannt eine Reihe von Rechenintensitäten, indem es die Anzahl der inneren Schleifendurchläufe variiert. Es eignet sich sowohl zur Untersuchung des Übergangs von speichergebundenen zu rechengebundenen Codes als auch zur Untersuchung von Stromverbrauch, Taktfrequenzen und Temperaturen beim Einsatz mehrerer GPUs. Das Shell-Skript series.sh erstellt für jeden Wert eine ausführbare Datei und führt sie nach Abschluss der Erstellung nacheinander aus.
Der Code läuft gleichzeitig auf allen verfügbaren Geräten. Beispielausgabe auf vier Tesla V100 PCIe 16 GB:
1 640 Blöcke 0 seine 0,125 Fl/B 869 GB/s 109 GF/s 1380 Mhz 138 W 60 °C2 640 Blöcke 0 seine 0,125 Fl/B 869 GB/s 109 GF/s 1380 Mhz 137 W 59 °C3 640 Blöcke 0 es ist 0,125 Fl/B 869 GB/s 109 GF/s 1380 Mhz 124 W 56°C0 640 Blöcke 0 seine 0,125 Fl/B 869 GB/s 109 GF/s 1380 Mhz 124 W 54°C1 640 Blöcke 8 seine 1,125 Fl/B 861 GB/s 968 GF/s 1380 Mhz 159 W 63°C0 640 Blöcke 8 seine 1,125 Fl/B 861 GB/s 968 GF/s 1380 Mhz 142 W 56°C2 640 Blöcke 8 seine 1,125 Fl/B 861 GB/s 968 GF/s 1380 MHz 157 W 62°C3 640 Blöcke 8 seine 1,125 Fl/B 861 GB/s 968 GF/s 1380 Mhz 144 W 59°C[...]0 640 Blöcke 64 seine 8,125 Fl/B 811 GB/s 6587 GF/s 1380 MHz 223 W 63 °C3 640 Blöcke 64 it 8,125 Fl/B 813 GB/s 6604 GF/s 1380 Mhz 230 W 66 °C1 640 Blöcke 64 it 8,125 Fl/B 812 GB/s 6595 GF/s 1380 Mhz 241 W 71 °C2 640 Blöcke 64 it 8,125 Fl/B 813 GB/s 6603 GF/s 1380 MHz 243 W 69 °C
Misst die Host-zu-Gerät-Übertragungsrate der cudaMemcpy-Funktion über einen Bereich von Übertragungsgrößen
Beispielausgabe für einen Tesla V100 PCIe 16 GB
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 % 32 KB 0,04 ms 0,93 GB/s 2,70 % 64 KB 0,04 ms 1,77 GB/s 5,16 % 128 KB 0,04 ms 3,46 GB/s 7,55 % 256 KB 0,05 ms 5,27 GB/s 1,92 % 512 kB 0,07 ms 7,53 GB/s 1,03 % 1024 kB 0,11 ms 9,25 GB/s 2,52 % 2048 kB 0,20 ms 10,50 GB/s 1,07 % 4096 kB 0,37 ms 11,41 GB/s 0,58 % 8192 kB 0,71 ms 11,86 GB/s 0,44 % 16384 kB 1,38 ms 12,11 GB/s 0,14 % 32768 kB 2,74 ms 12,23 GB/s 0,03 % 65536 kB 5,46 ms 12,29 GB/s 0,08 % 131072 kB 10,89 ms 12,32 GB/s 0,02 % 262144 kB 21,75 ms 12,34 GB/s 0,00 % 524288 kB 43,47 ms 12,35 GB/s 0,00 % 1048576kB 86,91ms 12,35GB/s 0,00%
Misst die CUDA Unified Memory-Übertragungsrate mithilfe eines STREAM-Triad-Kernels. Es werden verschiedene Datensatzgrößen verwendet, die sowohl kleiner als auch größer als der Gerätespeicher sind. Beispielausgabe auf einem Tesla V100 PCIe 16 GB:
Puffergröße Zeitspreizung Bandbreite 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
Misst die Latenz und den Durchsatz von FMA-, DIV- und SQRT-Vorgängen. Es scannt Kombinationen von ILP=1..8, indem es 1..8 unabhängige Abhängigkeitsketten generiert, und TLP, indem es die Warp-Anzahl auf einem SM von 1 bis 32 variiert. Die endgültige Ausgabe ist eine ILP/TLP-Tabelle mit dem Kehrwert Durchsätze (Zyklen pro Vorgang):
Beispielausgabe auf einem Tesla V100 PCIe 16 GB:
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
Einige Features können aus dem Plot extrahiert werden.
Latenzen:
DFMA: 8 Zyklen
DDIV: 112 Zyklen
DSQRT: 101 Zyklen
Durchsatz eines Warps (läuft auf einem SM-Quadranten), keine Abhängigkeiten:
DFMA: 1/4 pro Zyklus (ILP 2, zur Betriebsüberlappung)
DDIV: 1/112 pro Zyklus (kein ILP/Überlappung)
DSQRT: 1/101 pro Zyklus (kein ILP/Überlappung)
Durchsatz mehrerer Warps (alle SM-Quadranten), Abhängigkeiten irrelevant:
DFMA: 1 pro Zyklus
DDIV: 1/7,5 Zyklen
DSQRT: 1/9,6 Zyklen