Mit CUDA ist es nicht mehr notwendig eine graphische Oberfläche auf dem GPGPU Knoten zu haben. Doch was, wenn man den GPU-Teil einer Anwendung profilen möchte? Der CUDA-Profiler basiert auf QT und läuft auf einem nackten Knoten ohne X nicht.

Zum Glück ist die Profilingfunktionalität von CUDA auf niedrigerer Ebene realisiert und lässt sich durch Umgebungsvariablen steuern. Der graphische Profiler nimmt einem diese Arbeit lediglich ab und lässt einen intuitiver die zu messenden Metriken bestimmen.

Die für die Konfiguration zuständigen Umgebungsvariablen sind:

  • CUDA_PROFILE – Dies ist die einzige zwingend erforderliche Variable. Hat sie den Wert 1 werden Profiler-Daten geschrieben.
  • CUDA_PROFILE_CSV – Ist diese Variable auf 1 gesetzt werden die Daten als CSV geschrieben. Dieses kann dan später vom Visual Profiler importiert werden.
  • CUDA_PROFILE_LOG – Hier kann der Name der Log-Datei vorgegeben werden. Ansonsten wird profile.log verwendet.
  • CUDA_PROFILE_CONFIG – Hier kann eine Konfigurationsdatei angegeben werden in welcher spezifiziert wird welche Zähler mitprotokoliert werden sollen.

In der durch CUDA_PROFILE_CONFIG angegebenen Datei können bis zu vier Zähler angegeben sein. Jeder Zähler muss hierbei in einer eigenen Zeile stehen. Die möglichen Werte sind:

  • gld_incoherent – Anzahl der nicht zusammengefügten lesenden Zugriffe auf den globalen Speicher, funktioniert nicht auf GT200-basierten Karten.
  • gst_incoherent – Anzahl der nicht zusammengefügten schreibenden Zugriffe auf den globalen Speicher, funktioniert nicht auf GT200-basierten Karten.
  • gld_coherent – Anzahl der zusammengefügten lesenden Speicherzugriffe.
  • gst_coherent – Anzahl der zusammengefügten schreibenden Speicherzugriffe.
  • local_load – Anzahl der lesenden Zugriffe auf den lokalen Speicher.
  • local_store – Anzahl der schreibenden Zugriffe auf den lokalen Speicher.
  • branch – Gesamte Anzahl der Verzweigungen
  • divergent_branch – Gesamte Anzahl der Verzweigungen welche zu serialisierter Ausführung führten
  • instructions – Befehlszähler
  • warp_serialize – Anzahl von Threads in Warps die aufgrund von Adresskonflikten beim Zugfriff auf den gemeinsamen oder den konstanten Speicher.
  • cta_launched – Anzahl der ausgeführten Blöcke.
  • So ist es dann durchaus auch möglich die Graphikkartennutzung in MPI-Programmen zu profilen. Hierbei muss man lediglich beachten, dass jeder Prozess seine eigene Ausgabedatei verwendet. Bei OpenMPI 1.3 kann man z.B. die Umgebungsvariable OMPI_COMM_WORLD_RANK nutzen und den Aufruf des eigenen, hier beispielsweise meinCudaProgramm genannten Programmes durch ein kleiens Skript ersetzen.

    #!/bin/bash
    export CUDA_PROFILE=1
    export CUDA_PROFILE_CSV=1
    export CUDA_PROFILE_LOG=meinCudaProgramm.profile.csv
    ./meinCudaProgramm