Der Compute Work Distributor plant einen Thread-Block (CTA) auf einem SM nur dann, wenn der SM über ausreichende Ressourcen für den Thread-Block verfügt (gemeinsamer Speicher, Warps, Register, Barrieren, ...). Ressourcen auf Thread-Blockebene, wie z. B. gemeinsam genutzter Speicher, werden zugewiesen. Die Zuweisung erzeugt ausreichend Warps für alle Threads im Threadblock. Der Ressourcenmanager weist den SM-Unterpartitionen Warps mithilfe von Round Robin zu. Jede SM-Unterpartition enthält einen Warp-Scheduler, eine Registerdatei und Ausführungseinheiten. Sobald ein Warp einer Unterpartition zugeordnet ist, bleibt er auf der Unterpartition, bis er abgeschlossen ist oder von einem Kontextwechsel (Pascal-Architektur) vorbelegt wird. Bei der Wiederherstellung des Kontextschalters wird der Warp auf dieselbe SM-Warp-ID zurückgesetzt.
Wenn alle Threads in Warp abgeschlossen sind, wartet der Warp-Scheduler auf den Abschluss aller ausstehenden Anweisungen des Warps. Anschließend gibt der Ressourcenmanager die Ressourcen auf Warp-Ebene frei, die die Warp-ID und die Registerdatei enthalten.
Wenn alle Warps in einem Thread-Block abgeschlossen sind, werden Ressourcen auf Blockebene freigegeben und der SM benachrichtigt den Compute Work Distributor, dass der Block abgeschlossen wurde.
Sobald ein Warp einer Unterpartition zugewiesen ist und alle Ressourcen zugewiesen sind, wird der Warp als aktiv betrachtet, was bedeutet, dass der Warp-Scheduler den Status des Warps aktiv verfolgt. In jedem Zyklus bestimmt der Warp-Scheduler, welche aktiven Warps blockiert sind und welche zur Ausgabe einer Anweisung berechtigt sind. Der Warp-Scheduler wählt den Warp mit der höchsten Priorität aus und gibt 1-2 aufeinanderfolgende Anweisungen aus dem Warp aus. Die Regeln für die doppelte Ausgabe sind für jede Architektur spezifisch. Wenn ein Warp eine Speicherlast ausgibt, kann er weiterhin unabhängige Befehle ausführen, bis er einen abhängigen Befehl erreicht. Der Warp wird dann als blockiert gemeldet, bis der Ladevorgang abgeschlossen ist. Gleiches gilt für abhängige mathematische Anweisungen. Die SM-Architektur wurde entwickelt, um sowohl die ALU- als auch die Speicherlatenz zu verbergen, indem pro Zyklus zwischen Warps gewechselt wird.
In dieser Antwort wird der Begriff CUDA-Kern nicht verwendet, da dies ein falsches mentales Modell einführt. CUDA-Kerne sind Pipeline-Gleitkomma- / Ganzzahl-Ausführungseinheiten mit einfacher Genauigkeit. Die Ausgaberate und die Abhängigkeitslatenz sind für jede Architektur spezifisch. Jede SM-Unterpartition und SM verfügt über andere Ausführungseinheiten, einschließlich Lade- / Speichereinheiten, Gleitkommaeinheiten mit doppelter Genauigkeit, Gleitkommaeinheiten mit halber Genauigkeit, Verzweigungseinheiten usw.
Um die Leistung zu maximieren, muss der Entwickler den Kompromiss zwischen Blöcken und Warps und Registern / Thread verstehen.
Der Begriff Belegung ist das Verhältnis von aktiven Warps zu maximalen Warps auf einem SM. Die Kepler-Pascal-Architektur (außer GP100) verfügt über 4 Warp-Scheduler pro SM. Die minimale Anzahl von Warps pro SM sollte mindestens der Anzahl von Warp-Schedulern entsprechen. Wenn die Architektur eine abhängige Ausführungslatenz von 6 Zyklen hat (Maxwell und Pascal), benötigen Sie mindestens 6 Warps pro Scheduler, dh 24 pro SM (24/64 = 37,5% Belegung), um die Latenz abzudecken. Wenn die Threads Parallelität auf Befehlsebene aufweisen, kann dies verringert werden. Fast alle Kernel geben Anweisungen mit variabler Latenz aus, z. B. Speicherladevorgänge, die 80 bis 1000 Zyklen dauern können. Dies erfordert mehr aktive Warps pro Warp-Scheduler, um die Latenz zu verbergen. Für jeden Kernel gibt es einen Kompromiss zwischen der Anzahl der Warps und anderen Ressourcen wie gemeinsam genutztem Speicher oder Registern. Daher wird eine Optimierung für eine 100% ige Belegung nicht empfohlen, da wahrscheinlich ein anderes Opfer gebracht wird. Der CUDA-Profiler kann dabei helfen, die Gründe für die Ausgabe von Anweisungen, die Belegung und den Stillstand zu ermitteln, um dem Entwickler bei der Ermittlung dieses Gleichgewichts zu helfen.
Die Größe eines Gewindeblocks kann die Leistung beeinträchtigen. Wenn der Kernel große Blöcke hat und Synchronisationsbarrieren verwendet, können Barrierenstillstände ein Grund für das Stillstand sein. Dies kann durch Reduzieren der Verwerfungen pro Fadenblock verringert werden.