Accelerator Offloading mit GCC

Seit mehr als einer Dekade nutzen Entwickler GPUs auch jenseits der Computergrafik. Musste man Aufgaben anfänglich in hardwarekompatible Grafikprobleme überführen, existieren dank immer flexibler werdender Hardware inzwischen einfachere Methoden, von der hochparallelen GPU-Architektur zu profitieren.

In Pocket speichern vorlesen Druckansicht
Accelerator Offloading mit GCC
Lesezeit: 16 Min.
Von
  • Sebastian Bauer
Inhaltsverzeichnis

Um die Leistungsfähigkeit der Grafikkarten für andere Aufgaben nutzen zu können, haben sich in den letzten Jahren entsprechende Schnittstellen etabliert. Zu nennen sind in dem Zusammenhang CUDA von Nvidia und OpenCL, das die Khronos Group entwickelt. CUDA arbeitet exklusiv mit Nvidia-Hardware, während es von OpenCL unterschiedliche Implementierungen gibt, mit denen sich GPUs von AMD, Intel und Nvidia sowie andere Formen von Rechenbeschleunigern einbinden lassen, etwa Field Programmable Gate Arrays (FPGAs). Beide Schnittstellen haben gemeinsam, dass die Berechnungen durch das Aufstellen eines Kernels formuliert werden, der in der Regel in einer C-ähnlichen Sprache zu definieren ist. Die Verwaltung in OpenCL ist jedoch etwas komplexer, da Entwickler die Kernel selbst übersetzen müssen, ähnlich wie bei den Shadern in OpenGL. Der Aufwand, einen bestehenden Algorithmus auf eines der beiden Systeme abzubilden und gegebenenfalls mehrere Varianten zu pflegen, ist somit vergleichsweise hoch.

Ganz anders ist das zum Beispiel beim Programmierstandard OpenACC. Dessen Konzept ist dem von OpenMP ähnlich, das ursprünglich als eine Schnittstelle für Multiprocessing ersonnen und in Version 4.0 erweitert wurde, um theoretisch von beliebigen Beschleunigern zu profitieren. Beiden Projekten liegt die Idee zugrunde, den Quelltext in den Sprachen C, C++ oder Fortran mit Direktiven zu versehen, um parallele Abschnitte kenntlich zu machen. So ist die eigentliche Implementierung im Idealfall gar nicht anzupassen.

Wirft man einen Blick in die Release Notes von GCC, finden sich erste Anzeichen für die Unterstützung beliebiger Beschleuniger mit OpenMP oder OpenACC in der Version 5 aus dem Jahr 2015 (ältere Versionen von GCC unterstützten bereits Funktionen für Mehrkernprozessoren von OpenMP). Danach wurde in GCC 6 zunächst rudimentär die Zusammenarbeit mit der auf CUDA aufbauenden Nvidia-Hardware und Intels Xeon Phi verbessert und um HSA erweitert. Letzteres ist eine Architektur von AMD, die es ermöglicht, dass sich GPU und CPU einen Adressraum teilen. Leider sind die Implementierungen nicht symmetrisch: HSA funktioniert derzeit nur mit OpenMP und Nvidia nur mit OpenACC.

Der Artikel zeigt, wie Entwickler die aktuelle GCC-Version für das sogenannte Accelerator Offloading einrichten. Dabei liegt der Fokus auf OpenACC und ist damit zunächst auf Nvidia- oder Xeon-Phi-Hardware beschränkt. An dieser Stelle soll lediglich die Nvidia-Implementierung Thema sein, da die Hardware günstiger zu beschaffen ist und damit eine weitere Verbreitung haben sollte. Die Prozedur für andere, zukünftige Beschleunigerarten wird ihr allerdings ähnlich sein. Ganz konkret soll der Artikel demonstrieren, wie aufwendig es ist, in den Genuss von beschleunigtem OpenACC zu kommen, das in der Vergangenheit ausschließlich durch kommerzielle Compiler wie dem von PGI beziehungsweise Nvidia bedient wurde. In der Tat ist das Aufwendigste das Set-up der Umgebung, da von Haus aus kein Compiler einer gängigen Linux-Distribution das neue GCC-Feature aktiviert hat.

Vorausgesetzt wird ein aktuelles Linux-Betriebssystem wie Debian oder Ubuntu, das auf einer 64-Bit-Intel-Architektur läuft. Außerdem muss das CUDA-Toolkit installiert sein, je aktueller desto besser. Dabei lassen sich die distributionseigenen Quellen nutzen – der Name des Pakets für Debian Jessie (im non-free-Zweig) und Ubuntu lautet beispielsweise nvidia-cuda-toolkit. Ganz frische Pakete finden sich für zahlreiche Distributionen auf der Nvidia-Seite, wo auch Installationshinweise aufgeführt sind.

Für den vorliegenden Artikel wurde Version 7.5 von CUDA und dem zugehörigen Toolkit gewählt. Der Kommandozeilenpfad wurde mit

export PATH=/usr/local/cuda/bin/:$PATH

erweitert. Dort befinden sich die benötigten Tools nach der Installation. Bei distributionseigenen Quellen entfällt in der Regel das Anpassen des Suchpfads.

Es lohnt sich vorab zu verifizieren, ob die CUDA-Installation funktioniert. Notwendig, aber nicht hinreichend ist zum Beispiel, dass der Befehl nvidia-smi keine Fehlermeldung ausgibt. Ebenso muss der Assembler ptxas funktionieren. Nvidias Anleitung zur Installation von CUDA auf Linux ist in der Dokumentation zu finden.