Wie kann SIMD in OpenCL optimal genutzt werden?

8

Im Optimierungsleitfaden von Beignet, einer Open-Source-Implementierung von OpenCL für Intel-GPUs

  

Arbeitsgruppengröße sollte größer als 16 sein und ein Vielfaches von 16 sein.

     

Da zwei mögliche SIMD-Lanes auf Gen 8 oder 16 sind. SIMD nicht verschwenden   Bahnen, müssen wir diese Regel befolgen.

Auch in der Compute Architecture von Intel Prozessorgrafik Gen7.5 :

  

Für Produkte auf Gen7.5-Basis enthält jede EU sieben Threads für insgesamt 28 KB für die allgemeine Registerdatei (GRF).

     

...

     

Auf Gen7.5-Rechnerarchitektur verwenden die meisten SPMD-Programmiermodelle   Diese Style-Code-Generierung und EU-Prozessor-Ausführung. Effektiv,   Jede SPMD-Kernelinstanz scheint seriell und unabhängig innerhalb ihrer eigenen SIMD-Lane auszuführen .

     

Tatsächlich führt jeder Thread gleichzeitig eine SIMD-Width-Nummer von Kernel-Instanzen & gt; aus. Also für eine SIMD-16 Kompilierung eines Compute    Kernel ist es möglich für SIMD-16 x 7 Threads = 112 Kernel-Instanzen    gleichzeitig in einer einzigen EU ausgeführt werden. Ähnlich, für SIMD-32 x   7 Threads = 224 Kernel-Instanzen, die gleichzeitig auf einem einzigen Server ausgeführt werden   EU.

Wenn ich es richtig verstehe, indem ich SIMD-16 x 7 threads = 112 kernel instances als Beispiel verwende, um 224 Threads in einem EU auszuführen, muss die Arbeitsgruppengröße 16 sein. Dann wird der OpenCL-Compiler 16 Kernel-Instanzen in eine 16-Lane falten SIMD-Thread, und mache das 7 Mal in 7 Arbeitsgruppen und führe sie in einer einzigen EU aus?

Frage 1: Habe ich Recht, bis hier?

Allerdings OpenCL-Spezifikationen bieten auch Vektor-Datentypen. Somit ist es möglich, die SIMD-16-Rechenressourcen in einer EU durch herkömmliche SIMD-Programmierung (wie in NEON und SSE) vollständig zu nutzen.

Frage 2: Wenn dies der Fall ist, verwendet die Verwendung des Datentyps vector-16 bereits explizit die SIMD-16-Ressourcen und entfernt damit mindestens 16 Elemente pro Arbeit -Gruppenbeschränkungen. Ist das der Fall?

Frage 3: Wenn alle obigen Aussagen zutreffen, wie können die beiden Ansätze miteinander verglichen werden: 1) 112 Threads lassen sich durch OpenCL in 7 SIMD-16 Threads falten Compiler; 2) 7 native Threads, die für die explizite Verwendung von Vektor-16-Datentypen und SIMD-16-Operationen codiert sind?

    
user3528438 31.10.2015, 14:24
quelle

1 Antwort

1
  1. Fast. Sie machen die Annahmen, dass es einen Thread pro Arbeitsgruppe gibt (N.B.-Thread ist in diesem Kontext, was CUDA eine "Welle" nennt. In der Intel GPU-Sprache ist ein Arbeitselement ein SIMD-Kanal eines GPU-Threads). Ohne Untergruppen gibt es keine Möglichkeit, eine Arbeitsgruppengröße zu einem Thread zu machen. Zum Beispiel, wenn Sie eine WG-Größe von 16 wählen, ist der Compiler noch frei, SIMD8 zu kompilieren und es auf zwei SIMD8-Threads zu verteilen. Beachten Sie, dass der Compiler die SIMD-Breite auswählt, bevor die WG-Größe bekannt ist ( clCompileProgram vor clEnqueueNDRange ). Die Untergruppenerweiterung könnte Ihnen erlauben, die SIMD-Breite zu erzwingen, ist aber definitiv nicht implementiert GEN7.5.

  2. OpenCL-Vektortypen sind ein optionaler expliziter Vektorisierungsschritt über die implizite Vektorisierung, der bereits automatisch erfolgt. Verwenden Sie zum Beispiel float16 . Jedes der Arbeitselemente würde jeweils 16 Gleitkommazahlen verarbeiten, aber der Compiler würde immer noch mindestens SIMD8 kompilieren. Daher würde jeder GPU-Thread (8 · 16) Gleitkommazahlen verarbeiten (parallel dazu). Das könnte ein bisschen übertrieben sein. Idealerweise wollen wir unseren CL nicht explizit mit expliziten OpenCL-Vektortypen vektorisieren. Aber es kann manchmal hilfreich sein, wenn der Kernel nicht genug Arbeit leistet (zu kurze Kernel können schlecht sein). Irgendwo sagt float4 ist eine gute Faustregel.

  3. Ich glaube, du hast 112 Arbeitsaufgaben gemeint? Mit nativem Thread meinen Sie CPU-Threads oder GPU-Threads?

    • Wenn Sie CPU-Threads meinen, gelten die üblichen Argumente für GPUs. GPUs sind gut, wenn Ihr Programm nicht stark divergiert (alle Instanzen nehmen ähnliche Pfade ein) und Sie verwenden die Daten oft genug, um die Kosten für die Übertragung von und zur GPU (arithmetische Dichte) zu verringern.
    • Wenn Sie GPU-Threads (die GEN SIMD8 oder SIMD16-Kreaturen) meinten. Es gibt keine (öffentlich sichtbare) Möglichkeit, die GPU-Threads im Moment explizit zu programmieren ( EDIT siehe Untergruppen-Erweiterung (nicht verfügbar auf GEN7.5)). Wenn es Ihnen möglich wäre, wäre es ein ähnlicher Kompromiss mit der Assemblersprache. Der Job ist schwieriger und der Compiler leistet manchmal einfach einen besseren Job als wir, aber wenn Sie ein bestimmtes Problem lösen und ein besseres Domänenwissen haben, können Sie im Allgemeinen mit genügend Programmieraufwand (bis Hardwareänderungen und die Annahmen Ihres cleveren Programms) besser machen wird ungültig gemacht.)
Tim 31.10.2015 23:07
quelle

Tags und Links