Constantin Timm Informatik 12 TU Dortmund

Slides:



Advertisements
Ähnliche Präsentationen
Übersicht Anzeigegeräte Framebuffer Grundlagen 3D Computergrafik
Advertisements

Matrixmultiplikation
Programmieren im Großen von Markus Schmidt und Benno Kröger.
< CUDA implementation>
Informatik 12 | DAES Compilerbau Wintersemester 2010 / 2011 Dr. Heiko Falk Technische Universität Dortmund Lehrstuhl Informatik 12 Entwurfsautomatisierung.
2.3 Register-Transfer-Strukturen
Kapselung , toString , equals , Java API
6. Der OpenMP Standard Direktiven-basiertes API zur Programmierung von Parallelrechnern mit gemeinsamem Speicher für FORTRAN, C und C++
2.5 Vektorrechner & Multimedia-Erweiterungen
Datenbankzugriff im WWW (Kommerzielle Systeme)
SAP R/3 - Speichermanagement
1 Energiebewusste Compilierung für digitale Signalprozessoren Markus Lorenz Peter Marwedel Universität Dortmund Lehrstuhl Informatik XII Projekt Prozessorarchitekturen.
WS 2009/10 1 Systeme 1 Kapitel 1 Aufbau von Rechnern.
Java: Objektorientierte Programmierung
Java: Grundlagen der Sprache
OpenMP Präsentation im Rahmen des Seminars
© 2006 W. Oberschelp, G. Vossen Rechneraufbau & Rechnerstrukturen, Folie 12.1.
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 7 Claudio Moraga, Gisbert Dittrich FBI Unido
Studiengang Informatik FHDW
WIRTSCHAFTSINFORMATIK Westfälische Wilhelms-Universität Münster WIRTSCHAFTS INFORMATIK TotalView Debugger Vorgestellt von Marco Dyballa mail:
Zusammenfassung Vorwoche
PKJ 2005/1 Stefan Dissmann Zusammenfassung Vorwoche Methoden sind mit einem Namen versehene Programmabschnitte besitzen Rückgabetyp, Namen, Parameterliste.
Vorlesung 2 Rechnerarchitektur Universität Bielefeld – Technische Fakultät AG Rechnernetze und verteilte Systeme Peter B. Ladkin
Vorlesung 3: Verschiedenes Universität Bielefeld – Technische Fakultät AG Rechnernetze und verteilte Systeme Peter B. Ladkin
Rechnerarchitektur Vorlesung 2 Peter B. Ladkin
Introducing the .NET Framework
Brandenburgische Technische Universität Cottbus Program Profiling Andrzej Filipiak Übung Testen von Software SoSe 2006.
Inhalt Der Cell Prozessor Aufbau des Cells Platine Block Diagramm
Random Heightmap on GPU
Matrix Multiplication on CUDA
< Best practices >
1 Vorlesung 3 Verschiedenes Peter B. Ladkin
Beschleunigung Virtueller Privater Netze durch Netzwerkprozessoren
Ralf KüstersDagstuhl 2008/11/30 2 Ralf KüstersDagstuhl 2008/11/30 3.
Leitfaden Motivation Was ist CUDA ? NVIDIA Grafikkarte Programmierung
2.3 Register-Transfer-Strukturen
PRJ 2007/1 Stefan Dissmann Verkettete datenstruktur: Liste Problem: Liste, die eine beliebige Zahl von Elementen verwaltet Operationen: Erzeugen, Anfügen,
Entwicklung verteilter eingebetteter Systeme - Einführung
Silverlight Eine Einführung. Agenda 1.Was ist Silverlight? 2.Die Silverlight Philosophie 3.Vorstellung des Szenarios 4.Einführendes Beispiel 5.Konzepte.
LS 2 / Informatik Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)
Aufbau eines von-Neumann- Rechners Marcel Waldvogel.
Clustering mittels Grafikprozessor
Die Computer der Zukunft?
Service Computing   Prof. Dr. Ramin Yahyapour IT & Medien Centrum 19. Januar 2010.
Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Grundlagen der Informatik I Thema 16: Ausnahmebehandlung.
GPU Computing Burim Kameri Fachhochschule Hannover (FHH)
GPU Computing Burim Kameri Fachhochschule Hannover (FHH)
Einführung in die Programmierung Wintersemester 2009/10 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Programmierung
Windows Presentation Foundation WS 2013/14 Prof. Dr. Herrad Schmidt
Einführung in die Programmiersprache C 4
Auslegung eines Vorschubantriebes
Signal-Prozessoren DSV1, 2009, Hhrt, 1 Mikro-Prozessor Von Neumann-Architektur Daten und Programmcode im gleichen Speicher => Sequenzieller Zugriff auf.
Ein Vortrag von Simon Bayer
Multiprozessoren: Herausforderung für die Software
Programmieren in Assembler
JOMP
Parallele Programmierung mit Java, SS 2001 Spar/Timber - Programmiersprache und Compiler für high-performance Berechnungen Technische Universität München.
Parallelisierung für Multiprozessor-Maschinen
Central Processing Unit von David Kleuker und Thomas Auner
Parallele Programmierung im.NET Framework Darmstadt, Präsentation am Beispiel von C-Sharp (C#)  Wichtige Grundlagen  Generika, Delegate, Lambda,
Software Engineering SS04 Paralleles Programmieren FH Aachen, Prof. Dr.-Ing. Michael Trautwein Andrej Kühnal, Perez-Otuno Rodrigo.
PhysX auf der GPU in Batman: Arkham Asylum & bei Fluid Simulations Universität zu Köln Historisch-Kulturwissenschaftliche Informationsverarbeitung Softwaretechnologie.
Proseminar – Computer Graphics Nikolaos Tsanakas computer graphics & visualization OpenGL Shading Language.
Wissenschaftliches Programmieren „CUDA“ Achim Grolms Buyu Xiao Guanhua Bai Betreuer: Dipl.-Ing. Bastian Bandlow.
Aachen, Seminarvortrag Von: Lukas Abels-Vehns OpenCL mit Aparapi.
Vergleich der Frameworks OpenCL und CUDA zur GPGPU- gestützten Datenverarbeitung Leonid Kostrykin Matr.Nr.: Lehrstuhl.
Paralleleles Rechnen auf Grafikkarten Einführung Christian Schwarz.
Blowfish mit CUDA Dominik Oepen Inhalt ● Blowfish Grundlagen ● Implementierungsdetails ● Performance ● Fazit.
 Präsentation transkript:

Constantin Timm Informatik 12 TU Dortmund GPGPU-Programming Constantin Timm Informatik 12 TU Dortmund 2012/04/09 Diese Folien enthalten Graphiken mit Nutzungseinschränkungen. Das Kopieren der Graphiken ist im Allgemeinen nicht erlaubt.

Künstliche Intelligenz Motivation (1) General Purpose Computing on Graphics Processing Units (GPGPU) Einführung um CPU (bei Spielen) zu entlasten Physikalische Berechnungen Künstliche Intelligenz © www.geforce.com & fr.wikipedia

Motivation (2) GPUs haben eine große Anzahl von parallelen Rechenkernen Wie kann man diese effizient programmieren? Gut für datenparallele Programme void add_vector(int* in1, int *in2, int *out) { for ( int i = 0; i < N; ++i ) { out[i] = in1[i] + in2[i] ; } © Nvidia – Best Practice Guide

Motivation (3) Was sollte man bzgl. GPGPU-Applikationen beachten? Parallele Applikationen mit möglichst unabhängigen Operationen Kopier-Overhead für Daten GPU GPU CPU CPU

Geschichte der GPGPU-Programmierung (1) Bis zirka 2003 – 2004 Benutzung von Shader-Sprachen zur Programmierung Vertex- und Fragmentshaderprogramme void main(void) { gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); } © David Kirk/NVIDIA and Wen-mei W. Hwu, 2007-2009, University of Illinois

Geschichte der GPGPU-Programmierung (2) Ab 2004 Einführung von Sprachen zum Streamprocessing, z.B. BrookGPU Von der Stanford University Nutzung von GPUs als Coprocessor / Beschleuniger Versteckt Komplexität kernel void foo (float a<>, float b<>, out float result<>) { result = a + b; } float a<100>; float b<100>; float c<100>; foo(a,b,c);

Geschichte der GPGPU-Programmierung (3) Ab 2004 BrookGPU Komplexer Kompilervorgang Plattform-unabhängig BrookGPU-Kompilervorgang „brcc“: S2S-Compiler „brt“: Runtime © Stanford University Graphics Lab

Geschichte der GPGPU-Programmierung (4) Ab 2007 Einführung von CUDA „Compute Unified Device Architecture“ Framework für Streamprocessing auf Nvidia Grafikkarten Ursprünglich nur für Datenparallelität konzipiert Ab 2008 Einführung von OpenCL Allgemeines Framework für Streamprocessing auf Multi- und Manycore- Architekturen Für Daten- und Taskparallelität konzipiert Spezifikation durch Khronos: AMD, Apple, ARM, Creative, Google, Intel, TI, Samsung, Nvidia

CUDA Adaptiert das Streamprocessing-Konzept Elementare Programmierkomponente => Kernel Keine Rekursion Parameteranzahl ist nicht variabel Unterscheidung von Host- und GPU-Code void add_vector(int* in1, int *in2, int *out) { for ( int i = 0; i < N; ++i ) { out[i] = in1[i] + in2[i] ; } __global__ void add_vector (int* in1, int *in2, int *out) { int i = (blockIdx.x*blockDim.x)+threadIdx.x; out[i] = in1[i] + in2[i]; } add_vector<<<N,1>>>( in1, in2, out ); Vektoraddition in C Vektoraddition in Cuda

CUDA – Entwicklungsprozess Mehrstufig und kompliziert Programmierung von Code für einen Thread Spezifikation der Parallelität per Hand Viele statisch vorgegebene Größen

CUDA – Elemente des Frameworks Thread Instanz eines Kernels Block Gruppe von Threads Grid Gesamtheit aller Blocks Host Kernel 1 2 Device Grid 1 Block (0, 0) (1, 0) (0, 1) (1, 1) Grid 2 Block (1, 1) Thread (0,1,0) (1,1,0) (2,1,0) (3,1,0) (0,0,0) (1,0,0) (2,0,0) (3,0,0) (0,0,1) (1,0,1) (2,0,1) (3,0,1) __global__ void add_vector (int* in1, int *in2, int *out) { int i = (blockIdx.x*blockDim.x)+threadIdx.x; out[i] = in1[i] + in2[i]; } © Nvidia

CUDA – Kompilierung CUDA-Programme werden in einem mehrstufigen Verfahren kompiliert GPU- und Host-Code getrennt kompiliert GPU-Binaries in Host-Code eingebettet Neuster Compiler von Nvidia basiert auf LLVM

CUDA – Abbildungsbeispiel Kernel benötigt folgende Ressourcen 5 Register pro Thread 1052 Bytes Shared Memory per Block Grid size: 64 Blocks Block size: 256 Threads Grafikkarte (1 Streaming-Multiprocessor) 8152 Register 16384 Bytes Scratchpad-Speicher Max 768 Threads, 8 Blocks und 24 Warps Auslastung der Grafikkarte 768 Threads, 3 Blocks, 4608 Bytes Shared Memory und 3840 Register

CUDA - Speicherallokation cudaMalloc() Allokiert globalen Speicher auf der Grafikkarte cudaFree() Gibt allokierten Speicher auf der Grafikkarte frei cudaMemcpy() Kopiert in/aus/im globalen Speicher auf der Grafikkarte Grid Block (0, 0)‏ Block (1, 0)‏ Shared Memory Shared Memory Registers Registers Registers Registers Thread (0, 0)‏ Thread (1, 0)‏ Thread (0, 0)‏ Thread (1, 0)‏ Host Global Memory © Nvidia

CUDA - Speichertransfers Kopieren in/aus/im globalen Speicher Vom Host zur Grafikkarte Von der Grafikkarte zum Host Auf der Grafikkarte int *d_x; cudaMalloc((void**) &d_x, sizeof(int)); int x=0; cudaMemcpy(d_x, &x, sizeof(int), cudaMemcpyHostToDevice); int *d_y; cudaMalloc((void**) &d_y, sizeof(int)); int y=0; … cudaMemcpy(&y, d_y, sizeof(int), cudaMemcpyDeviceToHost); int *d_x,d_y; cudaMalloc((void**) &d_x, sizeof(int)); cudaMalloc((void**) &d_y, sizeof(int)); cudaMemcpy(d_x, d_y, sizeof(int), cudaMemcpyDeviceToDevice);

CUDA – Speicherzugriff Globaler/Shared Memory-Speicherzugriff Zugriff auf globalen/shared Speicher nicht synchronisiert Ausgang von Schreibe-/Leseoperationen auf gemeinsamen Speicher? Lösung: Atomare Operationen __global__ void add_vector_gpu (int* out) { *out+=5; } add_vector_gpu<<<1,5>>>(out); __global__ void add_vector_gpu (int* out) { atomicAdd(out,5); } add_vector_gpu<<<1,5>>>(out); Ergebnis? => out = 5 Ergebnis? => out = 25

CUDA – Thread Divergence (1) Ablauf der Threads Vorhersage der tatsächlichen Reihenfolge schwierig Kann von Programmierer erzwungen werden __global__ void update(int* x, int* y) { int i = threadIdx.x + blockDim.x * blockIdx.x; if (i == 60){ sharedX = *x; sharedX = 1; } syncthreads(); if (i == 100) *y = sharedX; update <<<2,512>>>(in,out); Ergebnis? => *out = 1; Ergebnis? => *out = ?

CUDA – Thread Divergence (2) Synchronisation über Blockgrenzen Problemlos, wenn Blocks auf gleichem SM allokiert Sonst Synchronisation problematisch __global__ void update_1(int* x, int* y) { int i = threadIdx.x + blockDim.x * blockIdx.x; if (i == 600) *x = 1; } __global__ void update_2(int* x, int* y) { if (i == 0) *y = *x; update_1 <<<2,512>>>(in,out); update_2 <<<2,512>>>(in,out); __global__ void update(int* x, int* y) { int i = threadIdx.x + blockDim.x * blockIdx.x; if (i == 600) *x = 1; syncthreads(); if (i == 0) *y = *x; } update <<<2,512>>>(in,out); Ergebnis? => *out = ?; Ergebnis? => *out = 1;

CUDA – Inline Assembly PTX-Code kann direkt im Kernel benutzt werden Code meist effizienter PTX-Instruktionen keine Hardwarebefehle __global__ void kern(int* x, int* y) { int i = threadIdx.x + …; if (i == 0) *x += 1; syncthreads(); if (i == 1) *y = *x; } __global__ void kern(int* x, int* y) { int i = threadIdx.x + blockDim.x * blockIdx.x; if (i == 0) asm("ld.global.s32 %r9, [%0+0];" "add.s32 %r9, %r9, 1;" "st.global.s32 [%0+0], %r9;" : :"r"(x)); syncthreads(); if (i == 1) *y = *x; }

Open Compute Language - OpenCL © http://www.khronos.org/developers/library/overview/opencl_overview.pdf

OpenCL: Vergleich zu CUDA Unterschied zum CUDA-Ansatz Taskparallelität kann modelliert werden OpenCL-Programme werden online compiliert Unterstützung von heterogenen Systemen Befehle, kleinster Nenner Ausführung auf Nvidia-GPU Nur anderes Frontend + API Leider schlechterer Compiler © Nvidia

OpenCL für heterogene Systeme OpenCL auf verschiedensten Plattformen zu finden ZiiLabs Tablets Samsung SnuCore © ZiiLabs & Samsung

OpenCL vs. CUDA: Platform Model Compute Device CUDA: Nvidia Grafikkarte IBM CELL Board Compute Unit CUDA: Streaming Multiprozessor IBM CELL PPU Processing Element CUDA: Streaming Prozessor IBM CELL SPU © AMD

OpenCL vs. CUDA: Memory Model © Nvidia & Patrick Cozzi, GPU Programming and Architecture, University of Pennsylvania

OpenCL vs. CUDA: Execution/Program. Model © Nvidia & Patrick Cozzi, GPU Programming and Architecture, University of Pennsylvania

OpenCL vs. CUDA: Task-Parallelität Einsortierung von OpenCL-Kernel in „Command Queue“ Synchrone Ausführung Asynchrone Ausführung Kernel A Kernel B Kernel C Kernel D

Zusammenfassung Grafikkarten können effizient zur Beschleunigung von parallelen Programmen eingesetzt werden NVIDIA setzt auf CUDA und OpenCL CUDA Programmierung ist zeitaufwendig OpenCL bietet Alternative zu CUDA Portablen Code Unterstützt Taskparallelität direkt