2 Punkte von GN⁺ 2025-02-27 | 1 Kommentare | Auf WhatsApp teilen
  • DeepGEMM ist eine Hochleistungsbibliothek für Tensor-Core-Kernel, die GEMM, fused MoE, MQA-Scoring, HyperConnection und weitere zentrale Rechenprimitiven moderner LLMs in einer einzigen CUDA-Codebasis bündelt
  • Alle Kernel werden zur Laufzeit als leichtgewichtige JIT-Module kompiliert; eine CUDA-Kompilierung während der Installation ist nicht nötig, vorausgesetzt werden C++20, CUDA Toolkit, PyTorch und CUTLASS 4.0 oder neuer
  • Es nutzt einige Konzepte aus CUTLASS und CuTe, stützt sich jedoch nicht stark auf Templates oder algebraische Strukturen und ist mit einer begrenzten Zahl zentraler Kernelfunktionen so gestaltet, dass der Einstieg in die NVIDIA-GPU-Kerneloptimierung leichter fällt
  • Der unterstützte Umfang umfasst FP8-, FP4- und BF16-GEMM, grouped GEMM, MQA-Logits-Kernel für DeepSeek v3.2 sowie Mega MoE, das Kommunikation und Berechnung überlappt; dabei gelten auf SM90 und SM100 unterschiedliche Speicherlayout-Beschränkungen
  • Trotz des schlanken Designs zielt es bei vielen Matrix-Shapes auf gleiche oder bessere Leistung als spezialisierte, manuell abgestimmte Bibliotheken und enthält ein Update, das auf H800 bis zu 1550 TFLOPS erreicht

Zweck und Design von DeepGEMM

  • DeepGEMM ist eine Bibliothek für Tensor-Core-Kernel, die die wichtigsten Rechenprimitiven aktueller großer Sprachmodelle in einer einzigen CUDA-Codebasis zusammenführt
    • GEMM: FP8, FP4, BF16
    • fused MoE mit überlappter Kommunikation: Mega MoE
    • MQA-Scoring für den lightning indexer
    • HyperConnection (HC)
  • Alle Kernel werden zur Laufzeit als leichtgewichtige Just-In-Time(JIT)-Module kompiliert
    • Während der Installation ist keine CUDA-Kompilierung erforderlich
  • Es verwendet einige Konzepte aus CUTLASS und CuTe
    • Stützt sich jedoch nicht stark auf schwere Template- oder algebraische Strukturen
    • Hält die Codebasis einfach, indem die Zahl zentraler Kernelfunktionen begrenzt wird
  • Trotz des leichten Designs wird angegeben, bei verschiedenen Matrix-Shapes gleichwertige oder bessere Leistung als spezialisierten, manuell abgestimmten Bibliotheken zu liefern

Wichtige Updates

  • Das Update vom 16. April 2026 umfasst Mega MoE, FP8xFP4-GEMM, FP4 Indexer, PDL und schnellere JIT-Kompilierung
    • Details unter #304
    • Mega-MoE-Benchmarks unter #316
  • Das Update vom 28. September 2025 ergänzt einen Scoring-Kernel für weighted ReLU MQA logits für den DeepSeek-v3.2-lightning-indexer
    • Details unter #200
  • Das Update vom 20. Juli 2025 unterstützt sowohl SM90 als auch SM100 und wurde vollständig auf ein JIT-CPP-Modul mit niedrigem CPU-Overhead refaktoriert
    • NVRTC und die SASS-Optimierung nach der Kompilierung sind deaktiviert
    • NVRTC ist als Unterstützung für später vorgesehen
    • Da NVCC 12.9 FFMA-Interleaving automatisch ausführt, wird die Optimierung nach der Kompilierung nicht mehr unterstützt
    • Details unter #112
  • Das Update vom 14. Mai 2025 fügt weight gradient-Kernel für dense und MoE backward hinzu
    • Details unter #95
  • Das Update vom 7. Mai 2025 bietet mit NVRTC-Unterstützung bis zu 10-fach schnellere Kompilierung
    • Aktivierbar mit DG_JIT_USE_NVRTC=1
    • In einigen Fällen kann es zu Leistungsverlusten kommen
    • Details unter #94
  • Das Update vom 18. April 2025 erreicht auf H800 bis zu 1550 TFLOPS

Anforderungen und Installationsablauf

  • Die Laufzeitumgebung erfordert eine GPU mit NVIDIA-SM90- oder SM100-Architektur
  • Die Softwareanforderungen sind wie folgt
    • Python 3.8 oder neuer
    • Compiler mit C++20-Unterstützung
    • CUDA Toolkit
      • SM90: CUDA 12.3 oder neuer
      • Für Spitzenleistung wird CUDA 12.9 oder neuer dringend empfohlen
      • SM100: CUDA 12.9 oder neuer
    • PyTorch 2.1 oder neuer
    • CUTLASS 4.0 oder neuer
    • {fmt}-Bibliothek
  • In einer Entwicklungsumgebung wird das Repository einschließlich Submodulen geklont und anschließend mit develop.sh die notwendigen Includes verknüpft und das CPP-JIT-Modul gebaut
  • Die Installation erfolgt durch Ausführen von install.sh; danach wird deep_gemm im Python-Projekt importiert

GEMM-Schnittstelle und Layout-Beschränkungen

  • Die Benennungskonvention der GEMM-Kernel in DeepGEMM lautet D = C + A @ B
  • Das Layout der Eingabe-Shapes basiert auf NT
    • fp8_gemm_nt führt D = C + A @ B.T aus
  • Die SM90-Implementierung unterstützt nur das NT-Speicherlayout
    • Entspricht einer Kombination aus row-major und col-major
  • Die SM100-Implementierung unterstützt alle Speicherlayouts NT, TN, NN, TT
  • Auf beiden Architekturen muss der LHS-Scaling-Faktor ein TMA-ausgerichtetes und transponiertes Layout haben
    • SM90 verlangt den Scaling-Faktor im FP32-Format
    • SM100 verlangt das gepackte UE8M0-Format, bei dem vier UE8M0 in ein torch.int gepackt werden
  • Aufgaben wie Eingabetransposition oder FP8-Casting müssen vom Nutzer separat erledigt werden
    • Die Bibliothek stellt einfache PyTorch-Hilfsfunktionen bereit, diese können jedoch langsam sein
    • Der Hauptfokus liegt auf der Optimierung der GEMM-Kernel

Dense und Grouped GEMM

  • Für grundlegendes nicht gruppiertes FP8-GEMM werden die Funktionen fp8_gemm_{nt, nn, tn, tt} verwendet
  • Grouped GEMM mit contiguous layout gruppiert im Unterschied zum klassischen grouped GEMM von CUTLASS nur entlang der M-Achse
    • N und K müssen fest sein
    • Das Design ist auf Situationen in MoE-Modellen zugeschnitten, in denen Experten dieselbe Shape teilen
  • Im Training-Forward-Pass oder beim Inference-Prefilling kann die Zahl der pro Experte verarbeiteten Tokens variieren
    • Die Form, bei der solche Tokens in einem einzigen Tensor aneinandergereiht werden, wird als contiguous layout bezeichnet
    • Jedes Expert-Segment muss auf die M-Blockgröße des GEMM ausgerichtet sein
    • Die Ausrichtungsanforderung lässt sich mit get_mk_alignment_for_contiguous_layout() prüfen
  • Für das Weight-Backward von MoE steht auch eine entlang der K-Achse gruppierte API bereit
    • M und N müssen fest sein
    • Relevante Funktion: k_grouped_fp8_gemm_tn_contiguous
  • In der Inference-Decoding-Phase wird masked grouped GEMM unterstützt, wenn CUDA graph aktiviert ist und die CPU die Token-Zahl pro Experte nicht kennt
    • Wird ein Mask-Tensor bereitgestellt, berechnet der Kernel nur gültige Bereiche
    • Die Funktion lautet m_grouped_fp8_gemm_nt_masked
    • Es gibt ein Beispiel, das die Ausgabe des Low-Latency-Kernels von DeepEP als Eingabe verwendet

MQA-Kernel für den DeepSeek-v3.2-Indexer

  • Die MQA-Kernel-Familie für V3.2 bietet eine non-paged- und eine paged-Version
    • non-paged ist für Prefilling
    • paged ist für Decoding
  • fp8_mqa_logits erhält 6 Eingaben
    • q: E4M3-Tensor, Shape [seq_len, num_heads, head_dim]
    • kv: E4M3-Tensor und Float-Scaling-Faktor
      • Die Tensor-Shape ist [seq_len_kv, head_dim]
      • Die Shape des Scaling-Faktors ist [seq_len_kv]
    • weights: Float-Tensor, Shape [seq_len, num_heads]
    • cu_seq_len_k_start, cu_seq_len_k_end: Int-Tensoren, Shape [seq_len]
    • clean_logits: Ob nicht belegte Logits auf -inf bereinigt werden sollen
  • Die Ausgabe-Tensor-Shape ist [seq_len, seq_len_kv] und stellt Token-zu-Token-Logits dar
  • Jedes q-Token i durchläuft kv-Token j von cu_seq_len_k_start[i] bis vor cu_seq_len_k_end[i]
    • Auf kv_j wird der Scaling-Faktor angewendet
    • Mit q[i, :, :] @ kv_j werden Werte pro Head berechnet
    • Nach Anwendung von ReLU werden sie mit weights[i, :] multipliziert und aufsummiert, um einen skalaren Logit zu erzeugen
  • Die Funktion der paged-Version heißt fp8_paged_mqa_logits

Mega MoE

  • Mega MoE fusioniert mehrere MoE-Stufen in einem einzigen Mega-Kernel
    • EP dispatch
    • linear 1, FP8xFP4
    • SwiGLU
    • linear 2, FP8xFP4
    • EP combine
  • Mega MoE überlappt NVLink-Kommunikation und Tensor-Core-Berechnung
  • Für die Ausführung ist ein Multi-Process-Start mit symmetric memory erforderlich
  • Der Nutzungsablauf ist wie folgt
    • Mit deep_gemm.get_symm_buffer_for_mega_moe wird ein symmetric-memory-Puffer allokiert
      • Erfordert PyTorch 2.9 oder neuer
    • Mit deep_gemm.transform_weights_for_mega_moe werden Gewichte einschließlich FP4 und UE8M0 SF in das benötigte Layout transformiert
    • Vor dem Aufruf werden Eingaben, Scaling-Faktor, Top-k-Index und Top-k-Gewicht in den Puffer kopiert
    • Mit deep_gemm.fp8_fp4_mega_moe wird der fused-Mega-MoE-Kernel ausgeführt
  • Ein vollständiges Beispiel für Multi-Process-Setup und Benchmarking findet sich in tests/test_mega_moe.py

Hilfsfunktionen und Umgebungsvariablen

  • Wichtige Hilfsfunktionen steuern Laufzeitressourcen, Alignment, JIT-Kompilierung und die Umwandlung von Scaling-Faktoren
    • deep_gemm.set_num_sms / get_num_sms: Maximale Zahl der zu verwendenden SMs setzen und abfragen
    • deep_gemm.set_tc_util / get_tc_util: Näherungswert für das Tensor-Core-Utilization-Verhältnis setzen und abfragen
    • deep_gemm.set_pdl / get_pdl: Programmatic Dependent Launch (PDL) aktivieren und deaktivieren
    • deep_gemm.set_mk_alignment_for_contiguous_layout / get_mk_alignment_for_contiguous_layout: M/K-Alignment auf Gruppenebene für contiguous layout setzen und abfragen
    • deep_gemm.transform_sf_into_required_layout: Scaling-Faktor in das erforderliche Layout transformieren
    • deep_gemm.get_tma_aligned_size: Erforderliche TMA-Alignment-Größe abfragen
  • JIT-bezogene Umgebungsvariablen steuern Debug-Ausgabe, Cache-Speicherort, Compiler-Auswahl und Profiling-Optionen
    • DG_JIT_DEBUG: Gibt JIT-Debug-Informationen aus
    • DG_PRINT_CONFIGS: Gibt die ausgewählte Konfiguration pro Shape aus
    • DG_JIT_CACHE_DIR: Cache-Verzeichnis für kompilierte Kernel, Standard ist $HOME/.deep_gemm
    • DG_JIT_USE_NVRTC: Verwendet NVRTC statt NVCC; schnellere Kompilierung möglich, aber in manchen Fällen geringere Leistung
    • DG_JIT_NVCC_COMPILER: Pfad zum NVCC-Compiler
    • DG_JIT_CPP_STANDARD: Version des C++-Standards, Standardwert ist 20
  • Es gibt auch Umgebungsvariablen für Debugging und Profiling
    • DG_JIT_DUMP_ASM, DG_JIT_DUMP_PTX, DG_JIT_DUMP_SASS: Dumps der PTX- und SASS-Ausgabe
    • DG_JIT_WITH_LINEINFO: Enthält Source-Line-Informationen für Profiling-Tools
    • DG_COMM_KERNEL_DEBUG: Initialisiert den symmetric buffer vor Mega-MoE-Aufrufen mit 0
    • DG_USE_NVIDIA_TOOLS: Überspringt internes Profiling beim Einsatz externer NVIDIA-Tools
  • Build-Optionen steuern Installation und Kernel-Ladeverfahren
    • DG_SKIP_CUDA_BUILD: Überspringt den Build der CUDA-Erweiterung während der Installation
    • DG_FORCE_BUILD: Erzwingt einen lokalen Build statt des Downloads eines vorgefertigten Wheels
    • DG_JIT_USE_RUNTIME_API: Verwendet die CUDA Runtime API zum Laden von Kerneln; benötigt CUDA Runtime 12.8 oder neuer

Lizenz und Zitation

  • Das DeepGEMM-Repository steht unter der MIT License
  • Das Projekt gibt an, von CUTLASS inspiriert zu sein
  • Der Titel des Zitierhinweises lautet DeepGEMM: clean and efficient BLAS kernel library on GPU

1 Kommentare

 
GN⁺ 2025-02-27
Meinungen auf Hacker News
  • FFMA-SASS-Interleaving sieht wirklich erstaunlich aus.
    Offenbar bemerkte man, dass die Performance der CUTLASS-FP8-Kernel zwischen NVCC 12.2 und 12.3 besser wurde, verglich das kompilierte SASS und fand heraus, dass bei mehreren FADD-Instruktionen ein Bit in einem Interleaving-Muster umgeschaltet war. Unter Bezug auf eine Open-Source-Implementierung eines CUDA-Assemblers erkannte man wohl, dass dieses Bit das Yield-Bit ist, das den aktuellen Warp abgibt, damit ein anderer Warp ausgeführt werden kann.
    Beeindruckend ist, dass daraus ein Skript entstand, das die FFMA-Instruktionen im kompilierten Binary patcht, und dabei nicht nur das Yield-Bit, sondern auch das Reuse-Bit umschaltet, weil Register-Reuse nicht möglich ist, wenn ein Warp abgibt. So lassen sich bei fein skaliertem FP8-GEMM MMA-Instruktionen und Promotion-FFMA-Instruktionen besser überlappen, was in manchen Fällen die Performance um mehr als 10 % steigert.

    • Soweit ich anderswo gelesen habe, ist diese Art von Vorgehen bei performancekritischer Optimierung von Matrixoperationen ziemlich typisch.
      Nur scheinen andere AI-Unternehmen bei diesem konkreten Problem die Notwendigkeit noch nicht gesehen und es deshalb nicht angewendet zu haben; am Ende werden aber vermutlich alle an einem ähnlichen Punkt landen.
    • Scott Gray hatte 2015 auf Maxwell genau so etwas und noch mehr bereits herausgefunden, und auch danach haben sich viele Leute ausführlich damit beschäftigt.
  • Solche Beispiele zeigen sehr gut, wie weit heutige Compiler davon entfernt sind, allein aus High-Level-Code die Hardware-Performance herauszuholen.
    Ich frage mich, was nötig wäre, damit klassische Compiler-Techniken oder KI-basierte Optimierungsagenten solche Ergebnisse liefern.

    • Vermutlich braucht es eine enorme Menge Trial-and-Error in einer Reinforcement-Learning-Feedbackschleife.
  • Die gemeldeten Speedup-Zahlen werden mit einer eigenen CUTLASS-basierten Baseline verglichen.
    Ich frage mich, ob jemand einen direkten Performancevergleich mit cuBLAS gemacht hat.
    Die CUTLASS-GEMM-Ergebnisse, die ich bisher gesehen habe, lagen gegenüber cuBLAS ungefähr innerhalb von 10 %. Wenn die im Paper genannten 2x bis 2,5x Verbesserungen erhalten bleiben, wäre das wirklich beeindruckend.

    • Normalerweise meide ich FP8 und bevorzuge I8, aber diese Frage hat mich neugierig gemacht, wie gut cuBLAS tatsächlich abschneidet.
      Zunächst braucht cuBLAS für Mixed-Precision-Operationen wie FP8 die Erweiterungs-API cuBLASLt.
      Außerdem werden naheliegend wirkende Typkombinationen wie E5M2 x E5M2 bei A x B nicht unterstützt, E5M2 x E4M3 dagegen schon; zudem bestehen weitere Einschränkungen, etwa dass auf Ampere, Hopper und Blackwell Matrix A immer in transponiertem Layout vorliegen muss.
      Ich habe den FP8-cuBLASLt-Benchmark in mein „Less Slow C++“-Repository <https://github.com/ashvardanian/less_slow.cpp> integriert und ihn der Liste bestehender cuBLAS- sowie selbst geschriebener CUDA/PTX-Benchmarks hinzugefügt.
      Ich lasse ihn auf einer H200-GPU laufen, die dieselbe Performance wie eine H100 haben sollte; bei quadratischen Eingaben erreicht der Durchsatz einen Peak von etwa 1,35 Peta-ops.
      256 liegt bei 2,68 T/s, 512 bei 20,49 T/s, 1024 bei 144,23 T/s, 2048 bei 665,68 T/s, 4096 bei 1,26 P/s, 8192 bei 1,34 P/s und 16384 bei etwa 1,23 P/s; das entspricht ungefähr 67 % der von NVIDIA für dichtes GEMM beworbenen Zahl <https://resources.nvidia.com/en-us-data-center-overview-mc/e...>.
    • Ich habe gehört, dass man mit CUTLASS bessere Performance als mit cuBLAS erreichen kann.
      Ich dachte, als Baseline habe man die bessere Variante aus cuBLAS und CUTLASS gewählt.
  • Solche Open-Source-Projekte zeigen wirklich gut das Ziel der Branche, Effizienz zu erreichen.
    Allerdings dürften die Nutznießer dieser Software eher große Anbieter sein, die Modelle in großem Maßstab serven – also potenzielle Konkurrenten von DeepSeek – und weniger die allgemeine Open-Source-Community, die lernen, experimentieren oder Modelle auf Consumer-Hardware bereitstellen möchte.

    • Bessere Effizienz kann am Ende für alle, auch für DeepSeek selbst, zu günstigerer Hardware führen.
  • Ich bin mir nicht sicher, ob die langfristige Richtung, immer stärker auf niedrigere Präzision zu optimieren, wirklich gut ist.
    Das bedeutet, dass Modelle tatsächlich ziemlich sparse sind; derzeit mag das stimmen, aber wahrscheinlich eher, weil in der Trainingsmethode schlechte Ideen stecken, und nicht, weil sie ihrem Wesen nach so sparse sein müssten.

    • Solange die Sparsity, die man geschenkt bekommt, funktioniert, sollte man sie genießen.
      Zu erreichen, dass man sehr gute Modelle nur mit höherer Präzision trainieren kann, ist ein Forschungsproblem; Low-Precision-Training und -Inference sind Engineering-Probleme.
      Seit den CNN-Zeiten, mindestens seit neun Jahren, machen wir solche Dinge, und ich denke, ein paar Jahre bleiben noch.
    • Da Aktivierungsfunktionen einen erheblichen Teil des dynamischen Bereichs von Gleitkommazahlen wegwerfen, ist ziemlich klar, dass ein großer Bereich für bereits gesättigte Aktivierungsabschnitte vermutlich nicht nützlich ist.
  • Das könnte durch MXFP, Blackwells native Microscaling-Unterstützung, bedeutungslos werden.
    Auf Hopper hat man das im Grunde manuell mit gröberer Granularität, dafür mit FP32-Skalierungskoeffizienten umgesetzt.

    • Stimmt.
      Solche hochwertigen öffentlichen Demonstrationen zeigen sehr gut, wo der Burggraben von $NVDA liegt.
      Universal-GPUs sind sehr flexibel: Man kann per Programmierung viele Aufgaben ausführen, die Hardwareanbieter anfangs nicht bedacht haben, die aber durchaus sinnvoll sind.
      Wenn man allerdings vorhersagt, dass die Zukunft immer stärker in Richtung dedizierter Hardwareunterstützung konvergiert und damit der Spielraum für solche Softwareoptimierungen verschwindet, dann bricht der sogenannte CUDA-Burggraben zusammen.
      Um im Spiel zu bleiben, reißt NVIDIA also den eigenen Burggraben selbst ein :p
  • Wow, es steht unter der MIT-Lizenz.
    Ich wünschte, große Anbieter würden diese Art von Open-Source-Zusammenarbeit übernehmen.

  • Ich frage mich weiterhin, warum es undokumentierte Befehle gibt
    Auch wenn sie nicht vollkommen stabil sind, fände ich es richtig, sie den Nutzern bereitzustellen
    Solche Dinge dürften intern dokumentiert sein, aber ich verstehe nicht, warum man sie nicht öffentlich macht
    Security by obscurity funktioniert nicht, und die Konkurrenz betreibt ohnehin Reverse Engineering für alles

    • Vermutlich aus ähnlichen Gründen, aus denen auch in dem, was wir bauen, undokumentierte Bereiche entstehen
      Es kann an Zeitmangel liegen oder daran, dass man für instabile oder experimentelle Funktionen keinen Support implizieren möchte
      Wenn sich der Schaden nur auf das Team am Nachbartisch beschränkt, ist es auch viel einfacher, etwas zu ändern
    • Schon die Annahme, „so etwas ist intern dokumentiert“, muss nicht stimmen
      Wahrscheinlich steht es höchstens in Architektur-Design-Dokumenten oder Spezifikationen, und solche Dokumente will man natürlich nicht teilen
  • Ehrlich gesagt liegt das außerhalb meines Nutzungsbereichs und Verständnisses
    Trotzdem ist es wirklich erfreulich und erfrischend, dass solche Entdeckungen und Verbesserungen geteilt werden, damit alle davon profitieren können

    • FFMA steht für Fused Floating-point Multiply-Add und ist ein grundlegender GPU-Befehl, der D = A*B + C in einem Schritt ausführt
      Er ist für Matrixmultiplikation und Deep-Learning-Workloads sehr wichtig
      In NVIDIAs SASS werden FFMA-Befehle als 64-Bit- oder 128-Bit-Befehle kodiert und besitzen mehrere Kontrollbits, die ihr genaues Verhalten bestimmen
      Wenn das yield-Bit gesetzt ist, signalisiert es dem Warp-Scheduler, dass der aktuelle Warp nach diesem Befehl die Ausführung abgeben kann, und die Hardware kann einen anderen Warp ausführen, um Latenzen zu verbergen
      GPUs erreichen durch massive Parallelität einen hohen Durchsatz, und wenn ein Warp etwa wegen Speicherzugriffen wartet, kann ein anderer Warp weiterlaufen
      Das reuse-Bit gibt an, ob Quellregister in der unmittelbar folgenden Operation wiederverwendet werden können; wenn das yield-Bit gesetzt ist, muss es zwingend ausgeschaltet sein
      Denn wenn ein Warp abgibt, ist er möglicherweise nicht der nächste, der ausgeführt wird, und ein anderer Warp kann den Zustand der Registerdatei verändern, sodass die Hardware nicht garantieren kann, dass Registerwerte über ein yield hinweg erhalten bleiben
      Wenn man die yield-Bits bei FFMA-Befehlen in einem alternierenden Muster setzt, erzeugt der Compiler explizite Scheduling-Punkte, an denen andere Warps vorankommen können; um die Korrektheit zu wahren, müssen dabei auch die reuse-Bits dieser Befehle gelöscht werden
      Diese Änderung hilft besonders dabei, die für Matrixmultiplikation zentralen MMA-Befehle mit den Promotion-FFMA-Befehlen zu überlappen, die FP8 zur Akkumulation in eine höhere Präzision umwandeln
      FP8-GEMM erfordert üblicherweise, Werte für die Akkumulation in eine höhere Präzision umzuwandeln und anschließend wieder zurückzuwandeln, wodurch zusätzliche FFMA entstehen; das senkt zwar die Anforderungen an die Speicherbandbreite, erzeugt aber ein komplexes Berechnungsmuster mit gemischten Promotion- und Demotion-Operationen
      „Feingranulares Skalieren“ scheint die sorgfältige Verwaltung der Präzision an mehreren Stellen der Berechnung zu bedeuten
      Die Manipulation des yield-Bits sorgt dafür, dass Rechenoperationen und Formatkonvertierungen besser interleaved werden, wodurch die GPU-Ausführungseinheiten effizienter genutzt werden; ohne diese Optimierung findet der Warp-Scheduler möglicherweise keine natürlichen Umschaltgelegenheiten, sodass Rechenressourcen schlechter ausgelastet werden