nvidia geforce 6800 ultra ddl

Transcription

nvidia geforce 6800 ultra ddl
Software Engineering für moderne, parallele Plattformen
9. GPGPUs: Grafikkarten als Parallelrechner
Dr. Victor Pankratius
Dr. Victor Pankratius, Dipl.Inform. Frank Otto
IPD Tichy – Lehrstuhl für Programmiersysteme
KIT – die Kooperation von Forschungszentrum Karlsruhe GmbH und Universität Karlsruhe (TH)
Agenda
GPGPU - Erläuterung
Motivation
Performanzaspekte
Beispiele: NVidia GeForce
Das CUDA-Programmiermodell
Organisation und Speichermodell
Ausgewählte Sprachkonstrukte
(V 2, Fokus auf allgemeine Programmierung, keine Grafik)
Ausblick
2
Dr. Victor Pankratius, Frank Otto
GPGPU – Was ist das?
GPGPU
engl. Abkürzung für
„General purpose computation on Graphics Processor Units (GPUs)“
Idee:
Nutzung von Grafikkarten als allgemeine Parallelrechner
3
Dr. Victor Pankratius, Frank Otto
Motivation
Performanz bei Gleitkommaberechnungen
Peak GFLOP/s
GT400: GeForce GT480
GT200: GeForce GTX 280
G92: GeForce 9800 GTX
G80: GeForce 8800 GTX
G71: GeForce 7900 GTX
G70: GeForce 7800 GTX
NV40: GeForce 6800 Ultra
NV35: GeForce FX 5950 Ultra
NV30: GeForce FX 5800
GT400
1250
1000
GT200
G92
750
G80
Ultra
G80
500
G71
250
G70
NV35
3GHz
Intel Core2 Duo
NV40
3.2GHz
Harpertown
NV30
Quelle: NVidia, Juni 2010
0
Jan
4
Jun
Apr
2003
2004
Dr. Victor Pankratius, Frank Otto
Jun
Mar
2005
2006
Nov
Mai
Jun
Jan
2007 2008 2010
Gründe für Gleitkomma-Performanz
Spezialisierung GPU vs. CPU
KontrollLogik
ALU
ALU
ALU
ALU
CPU geeignet für allgemeine Anwendungen
GPU gut geeignet für spezielle Anwendungen
Cache
mit großen Datenmengen, Datenparallelität, SIMDArbeitsweise
DRAM
 daher weniger komplexe Kontrollflusslogik nötig
mit großem Verhältnis
 Latenzzeiten bei Zugriff auf Hauptspeicher werden durch
viele Berechnungen, weniger durch Cache-Effekte amortisiert
DRAM
5
Dr. Victor Pankratius, Frank Otto
Beispiel - Nvidia GeForce 8
Graphics Processing Unit (GPU)
Prozessor,
je nach Modell ~450-600MHz,
32-Bit FPU,1024 Register
~16 KB
~86,4 GB/s
128 Prozessoren insgesamt, jeder
mit 96 Fäden in Hardware
Insgesamt 12288 HW-Fäden!
DRAM-Speicher auf Grafikkarte insg:
~640-768 MB
Neuere Entwicklung: GTX280 mit: 240 Prozessoren, 1GB RAM
6
Dr. Victor Pankratius, Frank Otto
6
Beispiel - Nvidia GeForce 400 Serie
Graphics Processing Unit (GPU)
GeForce GTX 465, 470, 480
Seit März/Mai 2010 auf dem Markt
352-480 Kerne
Grafik-Taktfrequenz 607-700 MHz
Prozessor-Taktfrequenz 1215-1400 MHz
Speicher
Taktfrequenz 1603-1848 MHz
Standard-Speicherkonfiguration 1024-1536 MB GDDR5
256-384 Bit Speicherschnittstelle
Bandbreite 102,6-177,4 GB/s
Quelle: http://www.nvidia.de/object/geforce_family_de.html
7
Dr. Victor Pankratius, Frank Otto
Wieso hat man bis jetzt nicht Grafikkarten als
„Parallelrechner“ benutzt?
Programmiermodelle waren traditionell speziell auf Grafikverarbeitung
ausgerichtet
Eingeschränkter Befehlssatz
Hardware-Nähe bei Programmierung
Allgemeine Programmierung der Grafikkarte eher Ausnahmefall
Verbesserungen in den letzten Jahren bei Grafikkarten
Mehr parallel arbeitende Einheiten
Mehr Speicher
höhere Bandbreite bei Hauptspeicherzugriff
Neue Trends:
Programmiermodelle werden erweitert und verallgemeinert
Standard-PCs haben leistungsfähige Grafikkarten
8
Dr. Victor Pankratius, Frank Otto
Das CUDA-Programmiermodell
CUDA: „Compute Unified Device Architecture“
Von NVidia entwickelt
Beinhaltet allgemeines Programmiermodell für
Grafikkarten
• Momentan realisiert als Erweiterung der
Programmiersprache C durch zusätzliche
Sprachkonstrukte
• Grafikkarte wird als Co-Prozessor für
datenparallele Verarbeitung verwendet
• Entwickler schreibt Programm, das
datenparallele Teile auf der Grafikkarte (GPU)
und den Rest auf dem Prozessor (CPU)
ausgeführt
• Sprachkonstrukte kennzeichnen entsprechende
Teile
9
Dr. Victor Pankratius, Frank Otto
Integrierter CPU+GPU
Quelltext
Nvidia C Compiler
GPU
CPU
Assembly Quelltext
CUDA
Standard C
Treiber
Compiler
GPU
CPU
Das CUDA-Programmiermodell
Unterschiede zw. Fäden auf GPU vs. CPU
Fäden auf GPU leichtgewichtig, wenig Mehraufwand bei Erstellung
GPU braucht eine große Zahl von Fäden (tausende!), um effizient zu
arbeiten
Empfehlung für GeForce 8: Etwa 5000 (!) Fäden
Multicore-CPUs im Vergleich dazu nur wenige Fäden
Datenparallele Teile eines Programms werden auf der GPU als sog.
Kernroutinen (engl. „Kernels“) ausgeführt
10
Dr. Victor Pankratius, Frank Otto
Das CUDA-Programmiermodell
Organisation von Fäden (1)
Wirtsrechner
Ein Kern wird mit Hilfe eines
Gitters aus Faden-Blöcken ausgeführt
GPU
(Host)
Gitter 1
Kern 1
Block
(0, 0)
Block
(1, 0)
Block
(2, 0)
Block
(0, 1)
Block
(1, 1)
Block
(2, 1)
Gitter 2
Kern 2
Block (1, 1)
Faden Faden Faden Faden Faden
(0, 0)
(1, 0)
(2, 0)
(3, 0)
(4, 0)
Faden Faden Faden Faden Faden
(0, 1)
(1, 1)
(2, 1)
(3, 1)
(4, 1)
Faden Faden Faden Faden Faden
(0, 2)
(1, 2)
(2, 2)
(3, 2)
(4, 2)
11
Dr. Victor Pankratius, Frank Otto
Dimensionen und Größe der Blöcke gleich
Ein Faden-Block besteht aus einer
(limitierten) Anzahl mehrerer Fäden, die
miteinander kooperieren können
Datenaustausch durch Zugriff auf
schnellen gemeinsamen Speicher
Fäden innerhalb eines Blocks können ihre
Zugriffe synchronisieren
Fäden aus verschiedenen Blöcken
können nicht miteinander kooperieren
Das CUDA-Programmiermodell
Organisation von Fäden (2)
Wirtsrechner
Fäden und Blöcke haben IDs
GPU
(Host)
Gitter 1
Kern 1
Block
(0, 0)
Block
(1, 0)
Block
(2, 0)
Block
(0, 1)
Block
(1, 1)
Block
(2, 1)
Gitter 2
Zur Vereinfachung der Adressierung:
Zählung in verschiedenen Dimensionen
möglich
Block: 1D, 2D
Faden: 1D, 2D, 3D
Kern 2
Beispiel GeForce 8800
Block (1, 1)
Faden Faden Faden Faden Faden
(0, 0)
(1, 0)
(2, 0)
(3, 0)
(4, 0)
Faden Faden Faden Faden Faden
(0, 1)
(1, 1)
(2, 1)
(3, 1)
(4, 1)
Faden Faden Faden Faden Faden
(0, 2)
(1, 2)
(2, 2)
(3, 2)
(4, 2)
12
Dr. Victor Pankratius, Frank Otto
Max. Fäden/Block: 512
Max. Länge einer Dimension: 65535
Das CUDA-Programmiermodell
Speichermodell (1)
Gitter
Block (0, 0)
Logische Sicht:
Jeder Faden kann folgende Zugriffe
durchführen
Block (1, 0)
Gemeinsamer Speicher
Gemeinsamer Speicher
Register
Register
Register
Register
Faden (0, 0)
Faden (1, 0)
Faden (0, 0)
Faden (1, 0)
Lokaler
Speicher
Lokaler
Speicher
Lokaler
Speicher
Lokaler
Speicher
Globaler
Speicher
Wirtsrechner
(Host)
Speicher mit konstanten Daten
(Initialisierung durch Host)
Wirtsrechner kann auf globalen,
konstanten und Textur-Speicher
lesend und schreibend zugreifen
Dadurch Kommunikation zw.
Wirtsrechner und GPU
TexturSpeicher
13
Register:
Lesen+schreiben
Lokaler Speicher:
Lesen+schreiben
Gemeinsamer Speicher im Block:
Lesen+schreiben
Globaler Speicher im Gitter:
Lesen+schreiben
Speicher mit konstanten Daten im
Gitter: Nur lesen
Textur-Speicher im Gitter: Nur lesen
Dr. Victor Pankratius, Frank Otto
Das CUDA-Programmiermodell
Speichermodell (2)
Gitter
cudaMalloc()
Block (0, 0)
Block (1, 0)
Gemeinsamer Speicher
Register
Faden (0, 0)
Register
Faden (1, 0)
Alloziert Speicher im
globalen Speicherbereich
Benötigt zwei Parameter:
Gemeinsamer Speicher
Register
Faden (0, 0)
Register
Adresse eines Zeigers zu Anfang
der allozierten Daten
Faden (1, 0)
Größe der Daten
Lokaler
Speicher
Lokaler
Speicher
Lokaler
Speicher
Globaler
Speicher
Wirtsrechner
(Host)
Speicher mit konstanten Daten
(Initialisierung durch Host)
TexturSpeicher
14
cudaFree()
Lokaler
Speicher
Dr. Victor Pankratius, Frank Otto
Gibt Speicher wieder frei
Benötigt Zeiger
Das CUDA-Programmiermodell
Speichermodell (3)
Gitter
cudaMemcpy()
Block (0, 0)
Block (1, 0)
Gemeinsamer Speicher
Register
Register
Speicher-Datentransfer
Benötigt vier Parameter
Gemeinsamer Speicher
Register
Zeiger auf Quelle, Ziel
Register
Anzahl zu kopierender Bytes
Faden (0, 0)
Faden (1, 0)
Faden (0, 0)
Art des Transfers
Faden (1, 0)
Host nach Host
Lokaler
Speicher
Lokaler
Speicher
Lokaler
Speicher
Host nach GPU
Lokaler
Speicher
GPU nach Host
Globaler
Speicher
Wirtsrechner
(Host)
Speicher mit konstanten Daten
(Initialisierung durch Host)
TexturSpeicher
15
Dr. Victor Pankratius, Frank Otto
GPU nach GPU
In CUDA 1.0 asynchron
Das CUDA-Programmiermodell
Speichermodell (4)
Physische Sicht
Globaler Speicher, Speicher für
konstante Daten und TexturSpeicher sind lediglich Regionen
im RAM-Speicher der Grafikkarte
Grafikkarte
Prozessorgruppe N
Prozessorgruppe 2
Prozessorgruppe 1
Gemeinsamer Speicher
Register
Prozessor 1
Register
Prozessor 2
Register
…
Instruktionseinheit
Prozessor M
Cache für konstante Daten
TexturCache
16
Dr. Victor Pankratius, Frank Otto
RAM-Speicher auf Grafikkarte
- Gobaler Speicher (hat keinen Cache!)
- Speicher mit konstanten Daten
- Texturspeicher
Das CUDA-Programmiermodell
Spracherweiterungen (1) - Variablen
Erweiterungen für
Variablendeklarationen
Ablageort
Sichtbarkeit
Lebensdauer
__device__ __local__
int localVar;
Lokaler
Speicher
Faden
Faden
__device__ __shared__
int sharedVar; Gemeinsamer
Block
Block
Globaler
Speicher
Gitter
Applikation
Speicher mit
konstanten
Daten
Gitter
Applikation
Speicher
__device__
int globVar;
__device__ __constant__ int constVar;
„auf GPU“
Zeiger sind nur auf globalen Speicher erlaubt.
17
Dr. Victor Pankratius, Frank Otto
Das CUDA-Programmiermodell
Spracherweiterungen (2) - Funktionen
Erweiterungen für
Funktionsdeklarationen
Nur
ausführbar
auf
Nur
aufrufbar
auf
__device__ float gpuFunction()
GPU
GPU
GPU
Wirtsrechner
Wirtsrechner
__global__ void
__host__
kernelFunction()
float hostFunction()
• device und global-Funktionen unterstützen keine
• Rekursion
• Deklaration statischer Variablen innerhalb der Funktion
• Variable Anzahl an Argumenten
18
Dr. Victor Pankratius, Frank Otto
Wirtsrechner
Das CUDA-Programmiermodell
Spracherweiterungen (3)
Eine Funktion, die auf der GPU ausgeführt werden soll, erhält eine
Ausführungskonfiguration
__global__ void
kernelFunktion(params);
//Aufruf
kernelFunktion<<<GitterDim, BlockDim, BytesSharedMem>>>(params)
Anzahl Blöcke im Gitter
Anzahl Fäden
in einem Block
Die Konfigurationsparameter der
Ausführungskonfiguration werden vor den
Funktionsparametern evaluiert. Alle Parameter
werden der GPU über den gemeinsamen Speicher
übergeben.
19
Dr. Victor Pankratius, Frank Otto
Größe des
gemeinsamen
Speichers, der
dynamisch pro Block
alloziert werden soll
Das CUDA-Programmiermodell
Spracherweiterungen (4)
Atomare Operationen
atomicAdd(), Sub, Min, Max, Inc, Dec
atomicAnd(), Or, Xor
atomicExch(), atomicCAS() //nur für globalen Speicher
Synchronisation
void __synchthreads();
Ist Barriere, die (nur) für alle Fäden in einem Block gilt
Sonst keine weiteren Synchronisationskonstrukte
20
Dr. Victor Pankratius, Frank Otto
Das CUDA-Programmiermodell
Spracherweiterungen (5)
Abfrage von IDs
threadIdx
Variable enthält den Index eines Fadens innerhalb eines Blocks
blockIdx
Variable enthält Index eines Blocks innerhalb eines Gitters
blockDim
Abfrage der Dimensionen eines Blocks (z.B. blockDim.x)
21
Dr. Victor Pankratius, Frank Otto
Das CUDA-Programmiermodell
Beispiel: Vektoraddition (1/2)
Ausführung auf GPU
//Berechne elementweise C = A + B
//jeder Faden führt Addition aus
//Aufruf von Wirtsrechner, Ausführung auf GPU
__global__ void vecAdd(float* A, float* B, float* C)
{
int i = threadIdx.x + blockDim.x * blockIdx.x;
Index eines Fadens
C[i] = A[i] + B[i];
}
22
Dr. Victor Pankratius, Frank Otto
#Fäden/Block
Index eines Blocks
Das CUDA-Programmiermodell
Beispiel: Vektoraddition (2/2)
int main() {
Ausführung auf Wirtsrechner (Host)
...
//alloziere & initialisiere Speicher für A, B auf Host
float *h_A=...; *h_B=...;
//alloziere
float *d_A,
cudaMalloc(
cudaMalloc(
cudaMalloc(
Speicher für A, B, C auf GPU
*d_B, *d, C;
(void**) &d_A, N*sizeof(float));
(void**) &d_B, N*sizeof(float));
(void**) &d_C, N*sizeof(float));
//kopiere Inhalte von Host auf GPU
cudaMemcpy( d_A, h_A, N*sizeof(float), cudaMemcpyHostToDevice) );
cudaMemcpy( d_B, h_B, N*sizeof(float), cudaMemcpyHostToDevice) );
//Vektoraddition für Vektorlänge N, mit N/256 Blöcken
//und mit je 256 Fäden pro Block
vecAdd<<<N/256, 256>>>(d_A, d_B, d_C);
23
}
Dr. Victor Pankratius, Frank Otto
Anmerkungen
CUDA-Konzept im Hinblick auf allgemeine Programmierung an vielen
Stellen noch verbesserbar bzw. erweiterbar
(z.B. bessere Transparenz der Speicherzugriffe,
Parallelisierungskonstrukte auf höherer Abstraktionsebene, …)
Vorgehen bei Fehlersuche
CUDA-Übersetzer in Emulationsmodus versetzen
Hardware + Fäden werden komplett auf CPU (sequenziell) emuliert
 Nutzung von Konsolenausgabe, setzen von Haltepunkten, usw. dann
möglich
FPUs halten sich bei Gleitkommaberechnungen nicht an den gängigen
IEEE 754-Standard
Numerische Ergebnisse können abweichen
24
Dr. Victor Pankratius, Frank Otto
CUDA 3.0
Einige Neuerungen und Verbesserungen
Unterstützung von C++ Template- und Klassenvererbung
Verbessert Programmierbarkeit / Produktivität
API für Direct3D und OpenGL
Verbesserung des Debuggers cuda-gdb
Performanz: Bis zu Faktor 100 schneller
Hardware-Unterstützung für Debugging in Anwendungen, welche die
CUDA Driver API verwenden
CUDA Memory Checker (neu)
u.a. Erkennung von „Out of Bounds“ Fehlern
Unterstützung von OpenCL
Mehr Informationen: http://developer.nvidia.com/object/cuda_3_0_downloads.html
25
Dr. Victor Pankratius, Frank Otto
OpenCL
Open Computing Language
www.khronos.org/opencl
„first open, royalty-free standard for general-purpose parallel
programming of heterogeneous systems”
Teilmenge von ISO C99 mit einigen Erweiterungen
Standard: Khronos Group
Ziel: Effizienter und portabler Code für heterogene Architekturen, die
gemischt aus Multikern-CPUs, GPUs, Cell oder z.B. DSP bestehen.
Start: Juni 2008; aktuell: V. 1.1 (Juni 2010)
IEEE 754 – konform
In Mac OS Snow Leopard bereits enthalten
Kernroutinen (Kerlnel) -Konzept ähnlich zu CUDA
26
Dr. Victor Pankratius, Frank Otto
OpenCL
Vergleich zu CUDA
Konzepte ähnlich (z.B. Kernel-Konzept, vgl. Vektoraddition-Bsp.)
Speichermodell
Quelle: http://www.khronos.org/developers/library/overview/opencl_overview.pdf
Synchronisation: Mit Barrieren, nur innerhalb einer “workgroup”
27
Dr. Victor Pankratius, Frank Otto
Ausblick
Weitere Co-Prozessor-Ansätze
Beispiel: Clearspeed Advance e720
Erweiterungskarte für PC
~96 GFLOPS
2GB RAM
Bandbreiten: 192 GB/s zum internen Speicher, 8GB/s zum Rechner-Hauptspeicher
32 + 64 Bit Genauigkeit
Konform zu IEEE-Gleitkomma-Standard
28
Dr. Victor Pankratius, Frank Otto