Open Source im professionellen Einsatz
Linux-Magazin 07/2010
© Glen Gaffney, 123RF.com

© Glen Gaffney, 123RF.com

Rechnen auf der Grafikkarte unter Linux

Parallel-Power

Auf einer Grafikkarte sitzen massenhaft Kerne. Deren summierte Rechenpower lässt sich außer zur Grafik-Ausgabe auch für andere Aufgaben nutzen - wenn diese parallelisierbar sind.

 

689

Moderne Grafikkarten zeichnen sich durch eine Vielzahl (mehrere Hundert) von parallel arbeitenden Kernen aus, die Berechnungen sehr schnell ausführen. Da sich die Hardware stark von der gebräuchlichen x86-Prozessorarchitektur unterscheidet, fordert die Programmierung besonders am Anfang einiges Umdenken vom Entwickler.

Programmierbar

Ein Grafikkartenprozessor (GPU, Graphics Processing Unit) arbeitet nach dem Pipeline-Prinzip: Mehrere hintereinander geschaltete Schritte berechnen den Farbwert eines Pixels. Die einzelnen Funktionen dieser Grafik-Pipeline waren bis vor wenigen Jahren hart verdrahtet. Die Hardware einer modernen GPU ist so aufgebaut, dass die einzelnen Module frei programmierbar sind. Damit sind Grafikkarten für alle interessant, die auch jenseits der Grafik-Ausgabe viel Rechenleistung benötigen und deren Aufgabenstellung parallelisierbar ist. Einen weiteren Schub für GPGPU (General Purpose Computation on GPU) hat gegeben, dass Nvidia diese Entwicklung unterstützt [1] und ein SDK herausgibt.

Was ist der Unterschied im Aufbau der Hardware zwischen einer CPU und einer modernen GPU mit mehreren Kernen? Es gibt hierzu eine sehr einfache Klassifikation aus der Informatik, die die Bearbeitung von Befehlen und Daten im Verhältnis zueinander beschreibt. Das erste Kriterium unterscheidet, ob die CPU in einem Schritt einen Befehl (SI, Single Instruction) oder unterschiedliche Befehle (MI, Multiple Instruction) abarbeitet. Das zweite Kriterium untersucht, ob der Prozessor einzelne Daten (SD, Single Data) oder eine Vielzahl unterschiedlicher Daten (MD, Multiple Data) parallel verarbeitet (siehe Abbildung 1).

Abbildung 1: Obwohl die Klassifikation von Flynn aus dem Jahr 1966 stammt, lassen sich auch heutige Systeme grob einer der Klassen zuordnen. Nur für MISD-Systeme gibt es keine sinnvolle Anwendung.

Der klassische x86-Rechner mit einem Kern (wie 486, Pentium) ist vereinfacht ein SISD-Rechner: Zu einem Zeitpunkt arbeitet die CPU genau eine Instruktion ab. Die inzwischen vorherrschenden Multicore-CPUs arbeiten nach dem MIMD-Prinzip. So können beispielsweise vier Kerne unabhängig voneinander unterschiedliche Befehle für unterschiedlichen Daten ausführen.

Ein Befehl, viele Daten

Moderne GPUs sind im Gegensatz dazu mit SIMD-Systemen verwandt: Sie führen auf unterschiedlichen Daten zu einem Zeitpunkt die identische Instruktion aus. Auf den klassischen, datenparallelen SIMD-Systemen läuft somit auf allen Recheneinheiten der identische Kontrollfluss. Eine If-Verzweigung mit alternativen Ablauffäden (Threads) ist nicht möglich. Nvidia hat die SIMD-Technik weiterentwickelt und nennt das Resultat SIMT, wobei MT für Multiple Threads steht. Sie macht es möglich, dass Threads unterschiedliche Pfade durch das Programm nehmen.

Das Listing 1 zeigt eine einfache C-Funktion, die als Parameter einen Index »i« und ein Feld »arr« von vorzeichenbehafteten ganzen Zahlen erhält und jeweils das Vorzeichen für ein Feldelement berechnet. Die Funktion gibt 1 für positive und -1 für negative Zahlen zurück. Ist die Zahl 0, dann bekommt der Aufrufer auch 0 zurück. Die Funktion lässt sich parallel ausführen, zum Beispiel auf einem Feld mit den Werten -12, 0, 24, 36. Ein vollwertiges MIMD-System mit vier Kernen und der gleichen Anzahl von Threads berechnet das Vorzeichen unabhängig voneinander. Jeder Thread durchläuft die Funktion unbeeinflusst von den anderen.

Listing 1: Unterschiedlicher
Kontrollfluss

01 signed int sign(unsigned int i, signed int arr[]) {
02         signed int result=0;
03         if (arr[i]>0)
04                 result=1;
05         else if (arr[i]<0)
06                 result=-1;
07         return result;
08 }

Reine SIMD-Systeme können die »sign«-Funktion nicht abarbeiten, weil der Kontrollfluss - abhängig vom Vorzeichen - unterschiedliche Pfade durchläuft. Auch die SIMT-Technologie führt nur einen Befehl zu einem Zeitpunkt aus. Aber ein Trick erlaubt es, Verzweigungen zuzulassen: Alle Threads, die denselben Pfad durch das Programm nehmen, ordnet die GPU einer Gruppe zu. Da der Befehl für alle Threads einer Gruppe identisch ist, läuft dieser parallel ab. Die Befehle unterschiedlicher Gruppen werden sequenziell ausgeführt. Die Konsequenz ist, dass nun auch verschiedene Pfade durch das Programm möglich sind.

Allerdings hat das Auswirkungen auf die Performance, denn es kommt zu Verzögerungen. Nur wenn alle Threads den gleichen Befehl ausführen, lässt sich das Maximum aus der Grafikkarte herausholen. In Abbildung 2 geben die grauen Kästchen die zeitliche Abarbeitung von Listing 1 an, die Zahlen entsprechen den Codezeilen.

Abbildung 2: SIMT-Systeme (links) verarbeiten zu einem Zeitpunkt nur einen Befehl parallel. Threads, die unterschiedliche Pfade nehmen, können daher nur sequenziell ablaufen. Für ausgewachsene Multicore-Systeme (rechts) gilt diese Einschränkung nicht. Die Zahlen entsprechen den Zeilennummern in Listing 1.

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 7 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

Linux-Magazin kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • Der Leih-Euler

    Moderne Grafikchips mir ihren vielfach parallelen Ausführungseinheiten rechnen on Board ungleich schneller als die Numerik-Einheiten aktueller CPUs. Für die neuesten Nvidia-Karten ist jetzt ein SDK für C-Programme erschienen, das die GPU als Rechenknecht beschäftigt.

  • Cuda 3.1: Update für Nvidias SDK

    Grafikchipspezialist Nvidia hat sein Development Kit für die Compute Unified Device Architecture (Cuda) erneuert.

  • Suricata

    Suricata, das wachsame Erdmännchen, heißt eine freie Software für die Intrusion Detection, die unter anderem von einer Stiftung des Homeland Security Department getragen wird. Die Snort-Alternative nutzt die GPU via Cuda, um auch in schnellen Netzen der herannahenden Daten Herr zu werden.

  • AMD veröffentlicht ATI Stream SDK 2.2

    Die neue Version der Entwicklungsumgebung für Anwendungen, die sowohl GPU- als auch CPU-Ressourcen verwenden, unterstützt neuere Versionen von OpenCL und Linux-Distributionen.

  • Facebook gibt schnelle Deep-Learning-Module für Torch frei

    Facebook AI Research (FAIR) veröffentlicht einige schnelle Deep-Learning-Module für Torch, eine Entwicklungsumgebung für maschinelles Lernen und Sehen, unter einer Open-Source-Lizenz.

comments powered by Disqus

Ausgabe 09/2016

Digitale Ausgabe: Preis € 6,40
(inkl. 19% MwSt.)

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.