Threading opencl compiling

8

[Update:] Ich spawn jetzt mehrere Prozesse und es funktioniert ziemlich gut, obwohl das grundlegende Threading-Problem noch besteht. [/]

Ich versuche ein c ++ (g ++ 4.6.1) Programm zu erstellen, das eine Menge opencl Kernel kompiliert. Die meiste Zeit wird in clBuildProgram verbracht. (Es ist genetische Programmierung und tatsächlich läuft der Code und Bewertung der Fitness ist viel viel schneller.) Ich versuche, die Kompilation dieser Kernel zu fädeln und bisher kein Glück zu haben. Zu diesem Zeitpunkt gibt es keine gemeinsamen Daten zwischen den Threads (abgesehen davon, dass sie die gleiche Plattform- und Gerätereferenz haben), aber es wird immer nur ein Thread gleichzeitig ausgeführt. Ich kann diesen Code als mehrere Prozesse ausführen (nur starten sie in verschiedenen Terminal-Windows in Linux) und es wird dann mehrere Kerne verwenden, aber nicht in einem Prozess. Ich kann mehrere Kerne mit demselben grundlegenden Threading-Code (std :: thread) mit nur einfacher Mathematik verwenden, also denke ich, dass es etwas mit der opencl-Kompilierung zu tun hat oder mit statischen Daten, die ich vergessen habe. :) Irgendwelche Ideen? Ich habe mein Bestes getan, um diesen Thread sicher zu machen, also bin ich ratlos.

Ich benutze AMDs SDK (opencl 1.1, ca. 6/13/2010) und eine 5830 oder 5850, um es auszuführen. Das SDK und g ++ sind nicht so aktuell wie sie sein könnten. Das letzte Mal, dass ich eine neuere Linux Distribution installiert habe, um das neuere g ++ zu bekommen, lief mein Code mit halber Geschwindigkeit (zumindest die Opencl Compiles waren), also ging ich zurück. (Ich habe nur den Code dieser Installation überprüft und er läuft mit halber Geschwindigkeit und ohne Threading-Unterschiede.) Wenn ich sage, dass nur ein Thread gleichzeitig läuft, werden alle gestartet und dann zwischen zweien gewechselt, bis sie beendet sind. dann mach die nächsten zwei usw. Und es sieht so aus, als ob alle Threads laufen, bis der Code das Programm erstellt. Ich verwende keine Callback-Funktion in ClBuildProgram. Mir ist klar, dass hier viel schief gehen kann, und ohne den Code ist es schwer zu sagen. :)

Ich bin mir ziemlich sicher, dass dieses Problem innerhalb oder im Aufruf von clBuildProgram auftritt. Ich drucke die Zeit, die hier drin ist, und die Threads, die verschoben werden, kommen mit einer langen Kompilierzeit für ihre erste Kompilierung zurück. Die einzigen gemeinsam genutzten Daten zwischen diesen ClBuildProgram-Aufrufen sind die Geräte-ID, da die cl_device_id jedes Threads denselben Wert hat.

So starte ich die Threads:

%Vor%

Dies ist der Punkt, an dem es nach unten geht (und dies sind alle lokalen Variablen, die übergeben werden, obwohl die Geräte-ID dieselbe ist):

%Vor%

Es scheint keinen Unterschied zu machen, ob jeder Thread einen eindeutigen Kontext oder eine Befehlswarteschlange hat. Ich habe wirklich vermutet, dass dies das Problem war, weshalb ich es erwähne. :)

Update: Das Erzeugen von Child-Prozessen mit fork () funktioniert dafür.

    
starship 27.01.2013, 05:48
quelle

1 Antwort

2

Vielleicht möchtest du etwas im AMD-Supportforum dazu posten. Angesichts der vielen fehlgeschlagenen OpenGL-Implementierungen über die Thread-Konsistenz, die die Spezifikation erfordert, würde es mich nicht überraschen, dass OpenCL-Treiber in diesem Sinne immer noch suboptimal sind. Sie könnten die Prozess-ID stattdessen intern verwenden, um Daten zu trennen, wer weiß.

Wenn Sie eine funktionierende multi-prozessierte Generation haben, dann schlage ich vor, dass Sie das behalten und Ergebnisse über IPC kommunizieren. Entweder können Sie boost :: ipc verwenden, das interessante Möglichkeiten zur Verwendung der Serialisierung bietet (z. B. mit boost :: spirit, um die Datenstrukturen widerzuspiegeln). Oder Sie können Posix-Pipes oder Shared Memory verwenden oder einfach Kompilierungsergebnisse in Dateien ablegen und das Verzeichnis mit boost :: filesystem und Verzeichnis-Iteratoren vom übergeordneten Prozess abfragen ...

Gespaltene Prozesse können einige Handles erben; Es gibt also Möglichkeiten, unbenannte Pipes zu verwenden. Ich glaube, das könnte Ihnen dabei helfen, einen Pipe-Server zu erstellen, der Client-Pipes instantiiert, was zu einer umfangreichen Protokollcodierung führen kann.

    
v.oddou 02.02.2013 02:34
quelle