OpenCL: Echte Herausforderungen - Seite 7

 

1) Pragmas ist eine Anforderung an die Kompilierzeitunterstützung, nicht die Aktivierung der Unterstützung selbst (wie Sie zu denken scheinen). Daher ist cl_khr_fp64 bereits involviert, wenn Ihr Visum es unterstützt.

2) Und wenn sich die Array-Größe zur Laufzeit ändert? Natürlich ist das in diesem speziellen Code möglich, aber es macht die Situation nicht besser.

Ich möchte Ihnen gleich sagen, dass ich in AMD CodeXL ein Profil erstellt habe:

3) Wenn wir nur die Rechenzeit des Kernels selbst betrachten, wird jede parallelisierte Aufgabe auf der GPU durch die Nutzung von mehr Kernen auf der CPU einen Vorteil haben. Schon 8 Aufgaben reichen also aus, um die Dinge zu beschleunigen.

4) Ich selbst habe eine Menge Fragen zur Formel für die lokale Berechnung. Der größte Gewinn wurde erzielt, als ich bei work_dim=1 die Aufgaben auf alle Kerne des Widgets verteilte, und das ist UNITS.

Und warum teilen Sie die Puffergröße im Allgemeinen, wenn Sie die Anzahl der Elemente teilen sollten? - was ich tatsächlich getan habe.

Mathemat: Kurz gesagt: Was muss Ihr Code leisten?

Um zu zeigen, dass die Vorbereitungsphase für die Berechnungen nicht sofort abläuft und die Übertragung von Puffern viel Zeit in Anspruch nimmt, wird die Praktikabilität der Verwendung von OpenCL sogar für befeuerte Aufgaben in Frage gestellt.

Außerdem wird angezeigt, dass die CPU im Testgerät nicht ausgewählt ist.

 
Roffild:

Es zeigt sich, dass die Vorbereitungsphase für die Berechnungen nicht sofort abläuft und die Pufferübertragung viel Zeit in Anspruch nimmt, was die Praktikabilität der Verwendung von OpenCL selbst für hochtrabende Aufgaben in Frage stellt.

Das heißt, es ist ziemlich albern, darüber zu schreien; es zu messen, ist dagegen etwas ganz anderes; es kann praktisch nützlich sein.

Außerdem wird angezeigt, dass die CPU im Testgerät nicht ausgewählt ist.

Vielleicht ist es gerechtfertigt, vielleicht ist es aber auch eine Überversicherung. Jedenfalls bin ich mir sicher, dass es bewusst gemacht wurde, um die Effizienz des Testprozesses selbst zu gewährleisten. Genauer gesagt, die Optimierung (da es sich um einen Multi-Thread-Prozess handelt). Hier können sich Chancen für eine Einbeziehung ergeben, wenn der Begriff des Testens und der Optimierung klar und vollständig getrennt werden (auf der Ebene der Parteipolitik), d.h. wenn wir sie als unterschiedliche logische Arten der Nutzung durch Tester definieren. Mit entsprechender (offiziell unterschiedlicher) Softwareunterstützung. (Das wäre in vielerlei Hinsicht gut, und ich bin ein langjähriger Befürworter einer solchen Trennung/Unterscheidung, bis hin zu verschiedenen Schaltflächen, um mit der Optimierung und dem Testen zu beginnen).

Theoretisch könnte dann die CPU-Auswahl während der Prüfung erlaubt und während der Optimierung verboten werden (was korrekt ist).

 
Roffild: 1) Pragmas sind eine Anforderung der Kompilierzeitunterstützung, nicht eine Aktivierung der Unterstützung selbst (wie Sie zu denken scheinen). Das heißt, cl_khr_fp64 ist bereits beteiligt, wenn die Eingeweide es unterstützen.

Ja, ich habe es mit dem Pragma übertrieben. Wenn Sie weiter an Ihrem Widget arbeiten und den Code nicht an andere weitergeben, ist das kein Problem. Aber wenn jemand sie auf einer Barts-Karte (z.B. 6870) lesen will, wird es Probleme geben. Der Kernel-Code wird versuchen, ohne Fehlermeldung ausgeführt zu werden.

4) Ich habe selbst eine Menge Fragen zur Formel für die Berechnung des Lokalen. Der größte Gewinn wurde erzielt, wenn work_dim=1 die Aufgaben auf alle Kerne des Widgets verteilt, was UNITS ist.

Nicht unbedingt. Es ist oft viel sinnvoller, die Arbeit im Kernel selbst zu erhöhen. Damit soll der mit der Datenübertragung verbundene Overhead ausgeglichen werden.

Und Ihre UNITS ist nur eine Anzahl von SIMD-Engines. In der Dokumentation heißt es dazu,

local_work_size[] legt eine Teilmenge von Aufgaben fest, die vom angegebenen OpenCL-Programmkern ausgeführt werden sollen. Seine Dimension ist gleich work_items[]und ermöglicht es, die Gesamtteilmenge der Aufgaben in kleinere Teilmengen ohne Teilungsrückstände zuzerlegen. Die Größe des Arrays local_work_size[] muss nämlich so gewählt werden, dass die globale Aufgabenmenge work_items[] in kleinere Teilmengen zerlegt wird. In diesem Beispiel istlocal_work_size[3]={10, 10, 10} ausreichend , dawork_items[40, 100, 320] ohne Rückstände aus dem Array local_items[10, 10, 10] zusammengesetzt werden kann .

Die SIMD-Engine-Nummer ist eine reine Hardware-Konstante, die die globale Aufgabe überhaupt nicht aufteilen muss.

Doch zunächst müssen Sie das globale Problem selbst richtig einschätzen.

Über die CPU im Testgerät - ich verstehe, ich bin überzeugt.

 
MetaDriver:

Das ist absolut nichts Neues, ich meine, es ist albern, darüber zu schreien, aber es zu messen ist eine andere Sache; es kann in der Praxis nützlich sein.

Nur dass ich aus irgendeinem Grund diese Messungen vornehmen musste... Wenn Sie lesen "es gibt eine Übertragungsverzögerung", haben Sie keine Ahnung, wie groß diese ist.

Mathemat: Und Ihre UNITS ist nur eine Anzahl von SIMD-Maschinen. In der Dokumentation heißt es dazu,

Die Anzahl der SIMD-Engines ist eine reine Hardwarekonstante, die die globale Aufgabe überhaupt nicht teilen muss.

Wir sollten besser die offizielle Dokumentation verwenden:

CL_DEVICE_MAX_COMPUTE_UNITS cl_uint Die Anzahl der parallelen Berechnungseinheiten auf dem OpenCL-Gerät. Eine Arbeitsgruppe wird auf einer einzigen Recheneinheit ausgeführt. Der Mindestwert ist 1.
local_work_size.
Zeigt auf ein Array von work_dim-Werten ohne Vorzeichen, die die Anzahl der Work-Items beschreiben, aus denen eine Work-Group besteht (auch als Größe der Work-Group bezeichnet), die den vom Kernel angegebenen Kernel ausführen wird.
Meine Schlussfolgerungen sind also richtig und werden durch den AMD CodeXL-Lauf bestätigt
 

Der Punkt ist ein anderer. Nennen Sie Ihre Einheiten Fässer, aber die Tatsache bleibt, dass Einheiten in Ihrem Code nicht teilen die globale Aufgabe Ganzzahl (meine sicherlich nicht: 240/28 ist nicht ganzzahlig; Ihre auch, da Sie units=18). Dies ist ein Fehler.

Und zweitens arbeiten Sie hier und jetzt mit OpenCL für MQL5 (na ja, das stimmt nicht, aber Sie haben mich erwischt); das ist ja ein anderes OpenCL als das von Khronos.

P.S. Ich habe den Hyperlink nicht erstellt; ich habe ihn mir einfach selbst besorgt :)

Roffild:
CL_DEVICE_MAX_COMPUTE_UNITS cl_uint Die Anzahl der parallelen Berechnungseinheiten auf dem OpenCL-Gerät. Eine Arbeitsgruppe wird auf einer einzigen Recheneinheit ausgeführt. Der Mindestwert ist 1.

Siehe andere Quellen für die Definition von "Recheneinheiten".

Übrigens, hier ist eine Tabelle aus meinem zweiten Artikel. Es wäre schön, wenn Sie all diese Recheneinheiten (18), Stromkerne (288), Verarbeitungselemente (1440), maximalen Wellenfronten/GPU (496) und Arbeitselemente/GPU (31744) verstehen würden. Ich habe es noch nicht herausgefunden.


 
Mathemat:

Der Punkt ist ein anderer. Nennen Sie Ihre Einheiten Fässer, aber die Tatsache bleibt, dass Einheiten in Ihrem Code nicht teilen die globale Aufgabe Ganzzahl (meine sicherlich nicht: 240/28 ist nicht ganzzahlig; Ihre auch, da Sie units=18). Dies ist eine Störung.

Warum haben Sie dann die Anzahl der Bytes auf 240 festgelegt? Sie können es vielleicht, aber die Grafikkarte kann es nicht. Also 240/8 = 30 Doppelte.

240 Byte ist die Größe des gesamten Puffers von 30 Doubles.

Und "einen ganzen Teiler wählen" ist nur eine Empfehlung aus der offiziellen Dokumentation. Und diese Empfehlung funktioniert nicht perfekt.

Und das mit den UNITS ist nicht von mir; es sind nur Ratschläge aus OpenCL-Foren. Ich habe es getestet und die maximale Geschwindigkeit erreicht...

Mathemat:

Und die zweite Sache: hier und jetzt arbeiten Sie mit OpenCL für MQL5 (na ja, das ist nicht richtig, aber Sie haben mich erwischt), wo es doch ein anderes OpenCL ist als das von Khronos.

Und was ist die "andere"?

Sie verwechseln proprietäre Implementierungen mit einfachen Wrappern. OpenCL MQL ist nur ein Wrapper über Khronos OpenCL API. Über den Unterschied zwischen OpenCL MQL und Khronos.

 
Mathemat: Übrigens, hier ist die Tabelle aus meinem zweiten Artikel. Es wäre schön, wenn Sie all diese Recheneinheiten (18), Stromkerne (288), Verarbeitungselemente (1440), maximalen Wellenfronten/GPU (496) und Arbeitselemente/GPU (31744) verstehen würden. Ich habe es noch nicht herausgefunden.

Recheneinheiten ist die Anzahl der gleichzeitig ausgeführten Aufgaben.

max wavefronts/GPU (496) und work-items/GPU (31744) sind die Warteschlange, die ausgeführt werden muss.

AMD CodeXL hat bereits eine Antwort auf all diese Fragen.

 
Roffild:

Recheneinheiten ist die Anzahl der gleichzeitig ausgeführten Aufgaben.

max wavefronts/GPU (496) und work-items/GPU (31744) sind die Warteschlange für die Ausführung.

AMD CodeXL kann Ihnen endlich helfen - es beantwortet alle diese Fragen.

Vielleicht verstehe ich etwas nicht, sorry, aber kennen Sie Alexey persönlich? Aber von der Seite sieht es nicht so aus..... Du sprichst zu dreist, klug wie alle werden? klug zu sein ist keine Sünde, sich damit unter Brüdern im Geiste zu brüsten ist allerdings beschämend...

 

Ich bin ein einfacher Kerl und ich antworte auf den Punkt.

Wenn Sie OpenCL wirklich verstehen und nicht nur vermuten wollen, müssen Sie AMD CodeXL einsetzen und Ihren eigenen C/C++ Wrapper erstellen.

Ich kann meinen Wrapper posten, aber er hat einige unlogische Zeilen aufgrund meiner mangelnden Praxis in C/C++.

 
Roffild: Warum haben Sie dann 240 Bytes als Basiszahl genommen? Sie können es vielleicht tun, aber die Grafikkarte kann es nicht. Also 240/8 = 30 Doppelte.

240 Bytes ist die Größe des gesamten Puffers von 30 Doubles.

Sehen Sie sich Ihren eigenen Code an:

uint units = (uint)CLGetInfoInteger(hcontext, CL_DEVICE_MAX_COMPUTE_UNITS);
uint global_work_offset[] = {0};
uint global_work_size[1];
uint local_work_size[1];
global_work_size[0] = ArraySize(price);
Print( "Глобальная задача = ", global_work_size[0] );  /// Это я добавил, вышло 240. Но это и так легко подсчитать: 30*double = 240
local_work_size[0] = global_work_size[0] / units;

Außerdem dividieren Sie in der letzten Zeile 240 durch 18 (das sind die Einheiten für Ihre Karte).

Und "die ganze Trennwand aufheben" ist nur eine Empfehlung aus den offiziellen Unterlagen. Und diese Empfehlung funktioniert nicht perfekt.

Wir arbeiten mit MQL5 OpenCL. Ich beziehe mich dabei auf die Dokumentation auf unserer Website. Natürlich schaue ich mir auch Khronos an.

Und was UNITS angeht, so sind das nicht meine eigenen Worte, sondern einige Ratschläge aus OpenCL-Foren. Ich habe es getestet und die maximale Geschwindigkeit erreicht...

Nun, ich habe die maximale Geschwindigkeit bei anderen Parametern. Und?

Wir wollen Ihnen nur eine grobe Vorstellung geben. 18 Aufgaben, die gleichzeitig auf GPU Flies laufen, sind das Maximum, das auf 4-5 Strings von CPUs erledigt werden kann. Und eine CPU mit x86-Emulation kann viel mehr Threads organisieren. Zumindest wenn es sich um Intel handelt. Mein früherer Pentium G840 (2 Kerne) erreichte eine Beschleunigung von etwa 70x - bei zwei Geräten! Ganz zu schweigen davon, was mein derzeitiger... i7, sozusagen.

Eine gut parallelisierte Aufgabe (sehen Sie sich die MetaDriver-Skripte aus dem ersten ocl-Zweig an) ermöglicht es, Geschwindigkeiten von bis zu 1000 oder mehr auf der GPU zu erreichen (im Vergleich zu 1 Thread auf der CPU in MQL5). Wenn Sie es nicht finden können, kann ich es für Sie herunterladen, damit Sie es auf Ihrer Karte ausprobieren können.

Wenn Sie OpenCL wirklich verstehen und nicht nur erahnen wollen, müssen Sie AMD CodeXL einsetzen und Ihren eigenen C/C++ Wrapper erstellen.

OK, ich werde es mir ansehen, danke.