2016-07-18 28 views
0

Ich versuche, folgende nested thread architecture zu konfigurieren.CUDA Thread Scheduling: benutzerdefinierte Thread-Swapping/Event-basierte Sperren?

| | | 
| | | 
||| ||| ||| 
|vv |vv |vv 
v v v 

Der Haupt-Thread wird erst fortgesetzt, nachdem die verschachtelten Threads abgeschlossen wurden.

Das Problem ist, dass ich in größeren Strukturen in Hunger Probleme auftreten kann, wie die verschachtelten Threads in was derzeit benutzerdefinierte Sperren mit einem Standard-Mutex While-Schleife laufen. Dies ist kein Problem, bis das Programm mehr Threads lädt, die die GPU tatsächlich gleichzeitig ausführen kann. Gibt es eine Möglichkeit, zwischen aktiven Threads basierend auf Mutex-Logik zu wechseln?

Antwort

2

Der von Ihnen angegebene Link behandelt CUDA Dynamic Parallelism (CDP).

Wenn Sie im Nicht-CDP-Modus Mutexe/Locks verwenden möchten, liegt es in der Verantwortung des Programmierers, sicherzustellen, dass alle erforderlichen Threads einen Vorwärtsfortschritt erzielen können. Es gibt keine Möglichkeit, zwischen aktiven Threads zu wechseln. Sobald ein Thread vom GPU-Scheduler aktiviert wurde, muss er eventuell einen Vorwärtsfortschritt machen können. Es wird einen Scheduler-Slot (ein Slot auf dem SM) verbrauchen, bis es dazu in der Lage ist. Du kannst das nicht ändern.

Es gibt eine Ausnahme im CDP-Fall, die nur für die Beziehung zwischen dem übergeordneten Kernel und den untergeordneten Kerneln gilt. Ein Parent-Kernel darf einen Child-Kernel starten, und der GPU-Thread-Scheduler "tauscht" gegebenenfalls die übergeordneten Kernel-Threads aus, so dass Child-Kernel-Threads weiterarbeiten können und schließlich die implicit oder explicit Synchronisation im Parent-Thread erfüllen Das hängt von der Fertigstellung der Child-Grids ab.

jedoch diese Ausnahme für den CDP Eltern/Kind-Fall bedeutet nicht, dass:

  1. Muttergewinde für andere Muttergewinde (vielleicht diejenigen, die auf einem Programmierer geschriebene Sperre oder Mutex drehen) getauscht werden
  2. Kind Threads für andere Kind Fäden

innerhalb eines Rasters, ob Eltern oder Kind getauscht werden, es liegt in der Verantwortung Programmierer Schlösser oder mutexes intelligent zu verwenden, so dass notwendige Vorwärtsbewegung durch das Gitter hergestellt werden, mit erwartet, dass die CUDA-Laufzeit Threads austauscht, denen auf einem SM ein aktiver Slot zugewiesen wurde.

Es ist auch nicht möglich, den Austausch von Threads in aktive SM-Slots explizit zu erzwingen. Implizite Methoden sind der bereits diskutierte CDP-Mechanismus, und CUDA stream priorities aber keiner garantiert, dass das Tauschen von Threads innerhalb eines bestimmten Gitters stattfinden wird.

(In Bezug auf die Stream-Prioritäten, in der aktuellen Implementierung glaube ich nicht, dass es Threads oder Threadblocks, die derzeit geplant sind, austauscht, bis sie abgeschlossen sind. Es ist eigentlich eine opportunistische Scheduling-Kontrolle, nicht eine präventive, die planen wird Threadblocks aus Strömen mit höherer Priorität, wenn sich die Opportunity - verfügbare Scheduling-Slots auf einem SM - präsentiert. Allerdings gibt es im CUDA-Ausführungsmodell nichts, was ausdrücklich verhindert, dass Stromprioritäten aktive Threadblocks auslagern, so dass dies möglich ist ändere in der Zukunft.)

+0

bin ich beim Lesen Ihrer Antwort richtig, da es eine andere Möglichkeit gibt, Threads von einem Kernel-Thread zu starten, als einen Kind-Kernel zu starten? – user2255757

+1

Nein, ich kenne keine andere Möglichkeit, Threads als den Kernel-Startprozess zu starten, und ich bin mir nicht sicher, welcher Teil meiner Antwort das anzeigt.Ein Thread, der als Teil eines Kernel-Starts gestartet wurde, wird erst dann "aktiv", wenn der GPU-Thread-Scheduler ihn einem verfügbaren Slot auf einem bestimmten SM zuweist. Sie haben (im Allgemeinen) keine Kontrolle über diesen Planungsprozess. –

+0

Ich habe CDP nicht verstanden genug, um Ihre Erklärung von Nicht-CDP vs CDP zu verstehen. gibt es eine Thread-Fusion? – user2255757