Multi-GPU-Computing:
Eins, zwei, drei, ganz viele
Jörn Dinkla
para//el 2015
Karlsruhe, 22. 4. 2015
Version 0.1
 Tablet, PC, Großrechner, Cloud, Spielkonsole,
Autos …
GPU-Computing ist überall
 Schnelle erste Erfolge
 2x – 5x Speedup
 Dann wird es schwieriger …
 Oft sind 10x drin
Speedup
2 3 4 5 6 7 8 9 10 11 ...
 Bis zu 16 GPU pro Knoten
 Abhängig von
 Mainboard, CPU, Chipsatz, PCIe-Controller
Multi-GPU
 2 GPUs
 3 GPUs
 …
 Erreichbar? Amdahl‘s Gesetz?
X-facher Speedup?
4 6 8 10 12 14 16 18 20
6 9 12 15 18 21 24 27 30
Frameworks im Überblick
C ++ 11
C ++
C
Device
Framework
CUDA
C++
AMP
DirectX
AMDTreiber
TDD
WDDM
Thrust
C++-
Wrapper
Libra...
 CUDA
⊕ Am meisten verbreitet
⊕ C++ 11
⊖ nur NVIDIA-Hardware
 C++ AMP
⊕ C++ 11
⊖ Einschränkungen wegen DirectX (bisher)
...
1. Partitioning
2. Communication
3. Agglomeration
4. Mapping
 Siehe http://www.mcs.anl.gov/~itf/dbpp/
PCAM-Methodik
 … und parallele Datenstrukturen
 … und partitionierte Datenstrukturen
 Aufgabenstellung ähnlich
 Egal ob Multi-
 -CP...
Speicher und Synchronisation
1 GPU, Daten passen
 Partionierung u. „Swapping“ erforderlich
1 GPU, Daten passen nicht
 Partionierung erforderlich
2 GPUs, Daten passen
Szenario für
den Vortrag
 Partionierung u. „Swapping“ erforderlich
2 GPUs, Daten passen nicht
 Listen, Arrays
 2D: Ebenen, Bilder
 3D: Volumen
 Ganz
 Als Vektor/Liste von Ebenen
 Grids, Gitter
 Einfach zu part...
Regelmäßige Datenstrukturen
Teilung nach Anzahl Elemente
x y*z x/2 * y
y z x*y/2
z 2 x*y*z/2
Kopie
 Bäume
 Teilbäume als Partitionen
 Graphen
 Zusammenhangskomponenten
 Klein genug? Gleich groß?
Unregelmäßige Datenst...
 Graph Partitioning / Clustering
 Aufteilung gemäß Kostenfunktion
 Im allg. NP vollständig
 Minimale „cuts“
 Social N...
 Homogen (Gleiche GPUs)
 Gleiche Arbeit
 Inhomogen (Unterschiedliche GPUs)
 Messen und gewichten
 Wie bei CPUs
 Work...
 Nicht das Rad neu erfinden!
 „best practices“
 „think parallel“
 Tip
 McCool et. al.
 „Structured Parallel Programm...
Parallele Patterns
Siehe http://www.parallelbook.com/
 P: Elemente
 C: Keine
 „embarassingly parallel“
 A: Granularität
 CPU vs. GPU
 Großer Unterschied!
 M:
 TBB, Open...
 Beispiele
 Durchschnitt, Smoothing
 PDEs
 P, A, M wie Map
 C: Nachbarschaft
 Optimierung
 Speicherzugriffe und Cac...
 Wärmeleitungsgleichung in 2D
 Stencil
o[x,y] += c* ( i[x-1,y] + i[x+1,y]
+ i[x,y-1] + i[x, y+1]
- 4 * i[x,y] )
Beispiel...
 Initialisiere Wärmequelle heat
 prev := 0
 Für alle Iterationen
 Addiere Wärmequellen prev += heat
 current := stenc...
 Daten
 Buffer(float) für Wärmequelle
 Buffer(float) für prev und current
 Kernel
 add_heat() bzw. mask()
 stencil()...
Obfuscation
Aus Wilt „The CUDA Handbook“, S. 218
„Index-
Schlacht“
OptimiertNachteil: Speicherorganisation
fest verdrahtet
 Größe / Extension
 width, height
 index(x,y)
 in_bounds(x,y)
 in_bounds_strict(x,y)
Extent2
0 1 2 3
0 0 1 2 3 4 5 6 ...
Stencil-Kernel (CUDA 7.0)
 Vor Kernel-Aufruf
 Wechsel der Abstraktionsebene
 Host zu Device
 Von C++-Datenstrukturen zu Device-Pointern
Aufruf d...
 Basis BaseBuffer
 HostBuffer
 Unpinned (C++)
 Pinned (CUDA, nicht swapbar)
 Lokaler Speicher (NUMA)
 DeviceBuffer (...
 GPU besteht aus mehreren SM/CU
 Thread-Block wird festen SM zugewiesen
 Warp / Wavefront
 Kleinste Scheduling-Einheit...
 Thread-Block (Work group, tile)
 Performance, abhängig von Hardware
 Grid (NDRange)
 Beispiel
 Daten 8x8
 Grid 2x2
...
 kernel<<<g, tb, sm, s>>>(params)
 Kernel-Konfiguration
 dim3 Grid g
 dim3 Thread-Block tb
 Größe des Shared-Memory s...
mask() / add_heat()
 Single Instruction Multiple Threads!
 Mask-Bit für jeden Thread im Warp
SIMT - Divergenz
0 1 2 3
int tid = treadIdx.x;
...
 CUDA
 Nsight (Visual Studio, Eclipse)
 nvvp, Visual Profiler (Eclipse)
 Kommandozeile nvprof
 OpenCL
 Intel Vtune (...
 Computation Bound
 Alle Prozessoren 100% ausgelastet
 Memory Bound
 Bandbreite zum Speicher voll ausgelastet
 Latenc...
NVVP sagt zu stencil()
Arithmetische
Intensität 1/5
 Nicht optimal
 Arithmetische Intensität niedrig
 #Berechnungen / #Speichertransfers
 Möglichkeiten
 Mask()
 Textur-...
 Partitionierte Map
Map mit Multi-GPU
 „Overlap“
Stencil mit Multi-GPU
 Halo
 Ghost Cells
 „Overlap“
Iterierter Stencil
 Initialisiere Wärmequelle heat
 Für jede GPU
 Initialisiere Buffer prev und current
 Kopiere Teil von heat auf‘s Devi...
 Host (wie bisher)
 Wärmequellen
 Endergebnis
 Benötigt pro GPU
 Buffer für prev und current
 Heat-Buffer (Ausschnit...
 cudaGetDeviceCount(int* count)
 Ermittelt Anzahl der Devices
 cudaGetDeviceProperties(cudaDevice
Prop* prop, int devic...
 Jeder Thread hat CUDA-Kontext
 Dieser speichert aktuelle GPU
 Kernel
 Nur Speicher auf gleichem Device!
 Vorsicht be...
Partition, CudaPartition
GPU
 Explizit einschalten
 cudaDeviceCanAccessPeer(&i,d,e)
 cudaDeviceEnablePeerAccess(e,0)
 Einschränkungen
 Nicht Windo...
2D-Partition
2D-Partition auf Device
 mask()-Kernel
 Verschiedene Extents für Quelle und Ziel
mask()
Erinnerung: mask()
mask() mit Offset
Pos2
 Mit_overlap zu mit_overlap
 Kernel nur für inneren Bereich aufrufen
stencil()
Erinnerung: stencil()
stencil() mit Offset
Multi-GPU in CUDA
Halo vergessen?
Kopieren der Halos
XExtent2
Region2
Init in CUDA
Update in CUDA #1
Update in CUDA #2
Async!
 Wichtig: cudaDeviceSynchronize() parallel
Analyse mit NVVP / Nsight
Orange seq.
Orange par.
 Aktuelle Hardware
 Intel i7-5930K, 4,0 Ghz
 16 GB DDR4 RAM, 2,4 Ghz
 2x NVIDIA GTX 970, Standard-Clocks
 2x 16x PCIe...
Speedups
10x
Speedups Multi-GPU
1,955x
 1,955 Speedup bei 2 GPUs
 Und was bei 3, 4 oder mehr Karten?
 Problem:
 PCIe-Bus skaliert nur begrenzt
 Bandbreite i...
 Lane ist 1 bit, full duplex
 Punkt-zu-Punkt Verbindung
 1,2,4,8,12 oder 16 Lanes
 Geschwindigkeiten
 2.0: pro Lane 5...
 Grafikkarte x16
 CPU hat 40 Lanes
 => max. 2 x16 + 1x8
 bis zu 4 x8
PCIe
D2D
 Anzahl PCIe-Slots auf Mainboard
 Anzahl Lanes des PCIe-Controller
 Anzahl der Switches / IOHs
 4, 8 oder 16 GPUs
 Wi...
PCIe Switch
D2D D2DD2D
 Kein D2D über QPI
NUMA
D2D D2D
 Rechts-Links
 „Rechts“ Erst Kopie von g zu g+1
 „Links“ Dann von g zu g -1
Kopieren der Halos
PCIe-Bus
 …
 Für alle Iterationen
 Für jede GPU
 Addiere Wärmequellen prev += heat
 current := stencil(prev)
 Tausche prev un...
Kopieren der Halo‘s #2
 Aktuelle GPUs können gleichzeitig
 Kernel, 1 Kopie hin u. 1 Kopie zurück
Streaming
 …
 Für alle Iterationen
 Für jede GPU
 Berechne nur den Halo („Spezialkernel“)
 Kopiere Asynchron zu Nachbarn
 Bere...
Kopieren der Halo‘s #2
Code-Komplexität
vs. Performance
 Abhängig von Implementierung und Hardware
 Wie groß sind die Halos?
 Lässt sich die Kopie hinter dem Kernel
verstecken...
 Viele melden Erfolge …
Linearer Speedup
http://on-demand.gputechconf.com/gtc/2015/posters/GTC_2015_Computational_Physics...
 2016 Pascal
 4 „Connections“ per GPU
 Jede 20GB/s peak, 16GB/s praktisch
 US DoE, Summit 2017 150-300 PetaFLOPS
NVLINK
C++ AMP
 Daten: array, array_view
 Kernel: parallel_for_each
Single GPU mit AMP
DoubleBuffer<T>
Single GPU mit AMP #2
 restrict(amp)
 Extent2 hat schon __device__
Extent2AMP
Single GPU mit AMP #3
x, y: andere
Reihenfolge!
 GPU heißt „accelerator“
 accelerator_view ist logische Sicht
 Argument zu parallel_for_each
Multi-GPU mit C++ AMP #1
v...
 array_view logische Sicht auf ein array
 array<float> name(size, view)
Multi-GPU mit C++ AMP #2
 „D2D“-Kopien
 Aber:
 Über Host
 Nicht parallel zu parallel_for_each
Multi-GPU mit C++ AMP #3
OpenCL-stencil()
Kein
Extent2
Kein C++
11
OpenCL und C++Bindings
 Platform
 Device
 Context
 Program
 Kernel
 Buffer, Image
 CommandQueue
 Event
Übersicht OpenCL
Platform
Device
 Context wird mit vector<> angelegt
 Für jedes Device eine Queue
Single-Context, Multi-Device
 OpenCL-Objekte „shared“
 MemObjects, Programs, Kernels
 MemObjects brauchen explizite Kopie
 Kein D2D
 Support für P...
 Pro Device einen Context
 Alles separat und redundant
 Evtl. einfacher zu programmieren
 Scatter/Gather/Broadcast sta...
 Von Single- zu Multi-GPU
1. Partionierung einführen
2. Vervielfachung der Datenstrukturen
3. Kernel erweitern
 Mit Offs...
 Parallele Algorithmen
 … und partitionierte Datenstrukturen
 Hardware
 PCIe-Problematik
 Kompetenter PC-Hersteller n...
Multi-Node
 Das gleiche Partitionierungsproblem
 Kommunikation zwischen Nodes
 Kein Shared-Host-Memory mehr
 MPI_Send()
 MPI_Rec...
 Titan
 18688 Opterons und 18688 Tesla K20X
 Nr. 2 in Top 500
Multi-Node
Nur am Rande
…
 Folien
http://dinkla.net/parallel2015
 Sourcecode
https://github.com/jdinkla/parallel2015_gpuco
mputing
Organisatorisch
 Schwerpunkte
 Parallele Systeme
 C++ und Java/JVM
 GPU-Computing
 CUDA, OpenCL, C++ AMP
 Big Data, BI, Data Science...
Multi-GPU-Computing: Eins, zwei, drei, ganz viele
Nächste SlideShare
Wird geladen in …5
×

Multi-GPU-Computing: Eins, zwei, drei, ganz viele

1.324 Aufrufe

Veröffentlicht am

Slides of my talk at the parallel 2015 conference in Karlsruhe.

Veröffentlicht in: Bildung
  • Als Erste(r) kommentieren

  • Gehören Sie zu den Ersten, denen das gefällt!

Multi-GPU-Computing: Eins, zwei, drei, ganz viele

  1. 1. Multi-GPU-Computing: Eins, zwei, drei, ganz viele Jörn Dinkla para//el 2015 Karlsruhe, 22. 4. 2015 Version 0.1
  2. 2.  Tablet, PC, Großrechner, Cloud, Spielkonsole, Autos … GPU-Computing ist überall
  3. 3.  Schnelle erste Erfolge  2x – 5x Speedup  Dann wird es schwieriger …  Oft sind 10x drin Speedup 2 3 4 5 6 7 8 9 10 11 … „Enabler“
  4. 4.  Bis zu 16 GPU pro Knoten  Abhängig von  Mainboard, CPU, Chipsatz, PCIe-Controller Multi-GPU
  5. 5.  2 GPUs  3 GPUs  …  Erreichbar? Amdahl‘s Gesetz? X-facher Speedup? 4 6 8 10 12 14 16 18 20 6 9 12 15 18 21 24 27 30
  6. 6. Frameworks im Überblick C ++ 11 C ++ C Device Framework CUDA C++ AMP DirectX AMDTreiber TDD WDDM Thrust C++- Wrapper Library OpenCL Bolt Intel AMD
  7. 7.  CUDA ⊕ Am meisten verbreitet ⊕ C++ 11 ⊖ nur NVIDIA-Hardware  C++ AMP ⊕ C++ 11 ⊖ Einschränkungen wegen DirectX (bisher) ⊖ geringe Verbreitung  OpenCL ⊕ Apple, Intel, AMD ⊖ Geringer Abstraktionsgrad, C99 ⊖ Nicht so viele Libraries wie bei CUDA Vor- und Nachteile
  8. 8. 1. Partitioning 2. Communication 3. Agglomeration 4. Mapping  Siehe http://www.mcs.anl.gov/~itf/dbpp/ PCAM-Methodik
  9. 9.  … und parallele Datenstrukturen  … und partitionierte Datenstrukturen  Aufgabenstellung ähnlich  Egal ob Multi-  -CPU,  -Core  oder -GPU Parallele Algorithmen
  10. 10. Speicher und Synchronisation
  11. 11. 1 GPU, Daten passen
  12. 12.  Partionierung u. „Swapping“ erforderlich 1 GPU, Daten passen nicht
  13. 13.  Partionierung erforderlich 2 GPUs, Daten passen Szenario für den Vortrag
  14. 14.  Partionierung u. „Swapping“ erforderlich 2 GPUs, Daten passen nicht
  15. 15.  Listen, Arrays  2D: Ebenen, Bilder  3D: Volumen  Ganz  Als Vektor/Liste von Ebenen  Grids, Gitter  Einfach zu partitionieren Regelmäßige Datenstrukturen
  16. 16. Regelmäßige Datenstrukturen Teilung nach Anzahl Elemente x y*z x/2 * y y z x*y/2 z 2 x*y*z/2 Kopie
  17. 17.  Bäume  Teilbäume als Partitionen  Graphen  Zusammenhangskomponenten  Klein genug? Gleich groß? Unregelmäßige Datenstrukturen
  18. 18.  Graph Partitioning / Clustering  Aufteilung gemäß Kostenfunktion  Im allg. NP vollständig  Minimale „cuts“  Social Networks und Big Data  Apache Spark und GraphX  Kernighan-Lin, 𝑂(𝑛3 )  Buluc et. al. „Recent Advances in GP“ 2013 Unregelmäßige Datenstrukturen
  19. 19.  Homogen (Gleiche GPUs)  Gleiche Arbeit  Inhomogen (Unterschiedliche GPUs)  Messen und gewichten  Wie bei CPUs  Work-Balancing / Job-Stealing  Scheduling-Theory  Divisible Load Theory Scheduling
  20. 20.  Nicht das Rad neu erfinden!  „best practices“  „think parallel“  Tip  McCool et. al.  „Structured Parallel Programming“  Intel-lastig, Cilk Plus, TBB Parallele Patterns
  21. 21. Parallele Patterns Siehe http://www.parallelbook.com/
  22. 22.  P: Elemente  C: Keine  „embarassingly parallel“  A: Granularität  CPU vs. GPU  Großer Unterschied!  M:  TBB, OpenMP, CUDA, etc. Map mit PCAM
  23. 23.  Beispiele  Durchschnitt, Smoothing  PDEs  P, A, M wie Map  C: Nachbarschaft  Optimierung  Speicherzugriffe und Cache  Berechnungen speichern Stencil mit PCAM
  24. 24.  Wärmeleitungsgleichung in 2D  Stencil o[x,y] += c* ( i[x-1,y] + i[x+1,y] + i[x,y-1] + i[x, y+1] - 4 * i[x,y] ) Beispiel: Heat-Simulation
  25. 25.  Initialisiere Wärmequelle heat  prev := 0  Für alle Iterationen  Addiere Wärmequellen prev += heat  current := stencil(prev)  Tausche prev und current Ablauf
  26. 26.  Daten  Buffer(float) für Wärmequelle  Buffer(float) für prev und current  Kernel  add_heat() bzw. mask()  stencil()  Optional  Buffer(uchar4)  Kernel für Umwandlung Zu implementieren …
  27. 27. Obfuscation Aus Wilt „The CUDA Handbook“, S. 218 „Index- Schlacht“ OptimiertNachteil: Speicherorganisation fest verdrahtet
  28. 28.  Größe / Extension  width, height  index(x,y)  in_bounds(x,y)  in_bounds_strict(x,y) Extent2 0 1 2 3 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3
  29. 29. Stencil-Kernel (CUDA 7.0)
  30. 30.  Vor Kernel-Aufruf  Wechsel der Abstraktionsebene  Host zu Device  Von C++-Datenstrukturen zu Device-Pointern Aufruf des Kernels Kernel-Aufruf
  31. 31.  Basis BaseBuffer  HostBuffer  Unpinned (C++)  Pinned (CUDA, nicht swapbar)  Lokaler Speicher (NUMA)  DeviceBuffer (CUDA)  ManagedBuffer (CUDA) Buffer
  32. 32.  GPU besteht aus mehreren SM/CU  Thread-Block wird festen SM zugewiesen  Warp / Wavefront  Kleinste Scheduling-Einheit  32 bei NVIDIA, 64 bei AMD  Occupancy Warps und Wavefronts W0SM* W1 W2 W3 W4 -- -- --
  33. 33.  Thread-Block (Work group, tile)  Performance, abhängig von Hardware  Grid (NDRange)  Beispiel  Daten 8x8  Grid 2x2  Block 4x4 Grid = Data/Block 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 Daten, Pixel, Voxel Grid
  34. 34.  kernel<<<g, tb, sm, s>>>(params)  Kernel-Konfiguration  dim3 Grid g  dim3 Thread-Block tb  Größe des Shared-Memory sm  cudaStream_t s  Oft abhängig vom Extent2  CudaExecConfig(Extent2& e) CudaExecConfig
  35. 35. mask() / add_heat()
  36. 36.  Single Instruction Multiple Threads!  Mask-Bit für jeden Thread im Warp SIMT - Divergenz 0 1 2 3 int tid = treadIdx.x; if (tid < 2) { call_expensive_function() } else { call_expensive_function2() } Warps Code
  37. 37.  CUDA  Nsight (Visual Studio, Eclipse)  nvvp, Visual Profiler (Eclipse)  Kommandozeile nvprof  OpenCL  Intel Vtune (*)  AMD CodeXL  C++ AMP  Visual Studio 2013  Concurrency Visualizer Profiling
  38. 38.  Computation Bound  Alle Prozessoren 100% ausgelastet  Memory Bound  Bandbreite zum Speicher voll ausgelastet  Latency Bound  Warten auf die Daten Arten der Auslastung
  39. 39. NVVP sagt zu stencil() Arithmetische Intensität 1/5
  40. 40.  Nicht optimal  Arithmetische Intensität niedrig  #Berechnungen / #Speichertransfers  Möglichkeiten  Mask()  Textur-Speicher ausprobieren  Stencil()  Zwischenspeichern im Shared-Memory Fazit Single GPU
  41. 41.  Partitionierte Map Map mit Multi-GPU
  42. 42.  „Overlap“ Stencil mit Multi-GPU
  43. 43.  Halo  Ghost Cells  „Overlap“ Iterierter Stencil
  44. 44.  Initialisiere Wärmequelle heat  Für jede GPU  Initialisiere Buffer prev und current  Kopiere Teil von heat auf‘s Device  prev := 0  Für alle Iterationen  Für jede GPU  Addiere Wärmequellen prev += heat  current := stencil(prev)  Tausche prev und current  Kopiere Halo/Ghost Cells zu Nachbarn  Kopiere Ergebnisse aller GPUs auf Host Ablauf (Multi)
  45. 45.  Host (wie bisher)  Wärmequellen  Endergebnis  Benötigt pro GPU  Buffer für prev und current  Heat-Buffer (Ausschnitt) Datenstrukturen (Multi)
  46. 46.  cudaGetDeviceCount(int* count)  Ermittelt Anzahl der Devices  cudaGetDeviceProperties(cudaDevice Prop* prop, int device)  Eigenschaften des Devices  cudaSetDevice(int device)  Setzt Device für aktuellen Thread  Betrifft alle folgenden cuda*-Funktionen Multi-GPU mit CUDA
  47. 47.  Jeder Thread hat CUDA-Kontext  Dieser speichert aktuelle GPU  Kernel  Nur Speicher auf gleichem Device!  Vorsicht bei Bibliotheken  Z. B. Thrust Multi-GPU mit CUDA
  48. 48. Partition, CudaPartition
  49. 49. GPU
  50. 50.  Explizit einschalten  cudaDeviceCanAccessPeer(&i,d,e)  cudaDeviceEnablePeerAccess(e,0)  Einschränkungen  Nicht Windows u. WDDM Peer-to-Peer-Kopien D2D
  51. 51. 2D-Partition
  52. 52. 2D-Partition auf Device
  53. 53.  mask()-Kernel  Verschiedene Extents für Quelle und Ziel mask()
  54. 54. Erinnerung: mask()
  55. 55. mask() mit Offset
  56. 56. Pos2
  57. 57.  Mit_overlap zu mit_overlap  Kernel nur für inneren Bereich aufrufen stencil()
  58. 58. Erinnerung: stencil()
  59. 59. stencil() mit Offset
  60. 60. Multi-GPU in CUDA
  61. 61. Halo vergessen?
  62. 62. Kopieren der Halos
  63. 63. XExtent2
  64. 64. Region2
  65. 65. Init in CUDA
  66. 66. Update in CUDA #1
  67. 67. Update in CUDA #2 Async!
  68. 68.  Wichtig: cudaDeviceSynchronize() parallel Analyse mit NVVP / Nsight Orange seq. Orange par.
  69. 69.  Aktuelle Hardware  Intel i7-5930K, 4,0 Ghz  16 GB DDR4 RAM, 2,4 Ghz  2x NVIDIA GTX 970, Standard-Clocks  2x 16x PCIe 3.0  OS  Windows 7 bzw. Ubuntu 14.10 Benchmark Testsystem
  70. 70. Speedups 10x
  71. 71. Speedups Multi-GPU 1,955x
  72. 72.  1,955 Speedup bei 2 GPUs  Und was bei 3, 4 oder mehr Karten?  Problem:  PCIe-Bus skaliert nur begrenzt  Bandbreite ist begrenzt  Anzahl der Geräte ist begrenzt Und bei mehr GPUs?
  73. 73.  Lane ist 1 bit, full duplex  Punkt-zu-Punkt Verbindung  1,2,4,8,12 oder 16 Lanes  Geschwindigkeiten  2.0: pro Lane 500MB/s, max. 8 GB/s  3.0: pro Lane 1GB/s, max. 16 GB/s (*)  Controller  Hat max. Anzahl Lanes PCIe
  74. 74.  Grafikkarte x16  CPU hat 40 Lanes  => max. 2 x16 + 1x8  bis zu 4 x8 PCIe D2D
  75. 75.  Anzahl PCIe-Slots auf Mainboard  Anzahl Lanes des PCIe-Controller  Anzahl der Switches / IOHs  4, 8 oder 16 GPUs  Wichtig ist die Bandbreite nicht zu überladen  Praxiserfahrung:  3 GPUs waren bei vielen Kopien schneller als 4 GPUs Anzahl der GPUs
  76. 76. PCIe Switch D2D D2DD2D
  77. 77.  Kein D2D über QPI NUMA D2D D2D
  78. 78.  Rechts-Links  „Rechts“ Erst Kopie von g zu g+1  „Links“ Dann von g zu g -1 Kopieren der Halos
  79. 79. PCIe-Bus
  80. 80.  …  Für alle Iterationen  Für jede GPU  Addiere Wärmequellen prev += heat  current := stencil(prev)  Tausche prev und current  Kopiere Halo/Ghost Cells zu Nachbarn  … Ablauf (Multi)
  81. 81. Kopieren der Halo‘s #2
  82. 82.  Aktuelle GPUs können gleichzeitig  Kernel, 1 Kopie hin u. 1 Kopie zurück Streaming
  83. 83.  …  Für alle Iterationen  Für jede GPU  Berechne nur den Halo („Spezialkernel“)  Kopiere Asynchron zu Nachbarn  Berechne Teil ohne Halo  … Modifizierter Ablauf (Multi)
  84. 84. Kopieren der Halo‘s #2 Code-Komplexität vs. Performance
  85. 85.  Abhängig von Implementierung und Hardware  Wie groß sind die Halos?  Lässt sich die Kopie hinter dem Kernel verstecken?  Ab wie vielen GPUs ist der Bus ausgelastet?  Gibt es Stau („contention“) auf dem Bus? Lohnt sich das?
  86. 86.  Viele melden Erfolge … Linearer Speedup http://on-demand.gputechconf.com/gtc/2015/posters/GTC_2015_Computational_Physics_03_P5122_WEB.pdf http://on-demand.gputechconf.com/gtc/2015/presentation/S5585-Wei-Xia.pdf
  87. 87.  2016 Pascal  4 „Connections“ per GPU  Jede 20GB/s peak, 16GB/s praktisch  US DoE, Summit 2017 150-300 PetaFLOPS NVLINK
  88. 88. C++ AMP  Daten: array, array_view  Kernel: parallel_for_each
  89. 89. Single GPU mit AMP
  90. 90. DoubleBuffer<T>
  91. 91. Single GPU mit AMP #2
  92. 92.  restrict(amp)  Extent2 hat schon __device__ Extent2AMP
  93. 93. Single GPU mit AMP #3 x, y: andere Reihenfolge!
  94. 94.  GPU heißt „accelerator“  accelerator_view ist logische Sicht  Argument zu parallel_for_each Multi-GPU mit C++ AMP #1 view
  95. 95.  array_view logische Sicht auf ein array  array<float> name(size, view) Multi-GPU mit C++ AMP #2
  96. 96.  „D2D“-Kopien  Aber:  Über Host  Nicht parallel zu parallel_for_each Multi-GPU mit C++ AMP #3
  97. 97. OpenCL-stencil() Kein Extent2 Kein C++ 11
  98. 98. OpenCL und C++Bindings
  99. 99.  Platform  Device  Context  Program  Kernel  Buffer, Image  CommandQueue  Event Übersicht OpenCL Platform Device
  100. 100.  Context wird mit vector<> angelegt  Für jedes Device eine Queue Single-Context, Multi-Device
  101. 101.  OpenCL-Objekte „shared“  MemObjects, Programs, Kernels  MemObjects brauchen explizite Kopie  Kein D2D  Support für Partitions / Multi-GPU  Offsets für Kernel und Kopien  SubBuffer Single-Context, Multi-Device
  102. 102.  Pro Device einen Context  Alles separat und redundant  Evtl. einfacher zu programmieren  Scatter/Gather/Broadcast statt SubBuffer  Aufpassen bei der Datenhaltung  Einfache Erweiterung  Multi-Node oder heterogenes System Multi-Context & Multi-Device
  103. 103.  Von Single- zu Multi-GPU 1. Partionierung einführen 2. Vervielfachung der Datenstrukturen 3. Kernel erweitern  Mit Offsets und weiteren Extents Zusammenfassung
  104. 104.  Parallele Algorithmen  … und partitionierte Datenstrukturen  Hardware  PCIe-Problematik  Kompetenter PC-Hersteller notwendig  Fazit  Gute Speedups möglich  Wenn Halo-Kopien klein  und/oder hinter Kernel versteckt  Skaliert wegen PCIe nur begrenzt Fazit
  105. 105. Multi-Node
  106. 106.  Das gleiche Partitionierungsproblem  Kommunikation zwischen Nodes  Kein Shared-Host-Memory mehr  MPI_Send()  MPI_Recv()  GPU-spezifische Erweiterungen  OpenMPI, MVAPICH2 Multi-Node mit MPI
  107. 107.  Titan  18688 Opterons und 18688 Tesla K20X  Nr. 2 in Top 500 Multi-Node Nur am Rande …
  108. 108.  Folien http://dinkla.net/parallel2015  Sourcecode https://github.com/jdinkla/parallel2015_gpuco mputing Organisatorisch
  109. 109.  Schwerpunkte  Parallele Systeme  C++ und Java/JVM  GPU-Computing  CUDA, OpenCL, C++ AMP  Big Data, BI, Data Science  http://www.dinkla.com Last but not least Fragen? Sprechen Sie mich an oder joern@dinkla.com

×