2016-08-01 18 views
1

Was kostet das Umwandeln einer Variablen in OpenCL in einen anderen Typ?OpenCL: Typkonvertierungs-Overhead

Beispiel: I Punktprodukt von 2 int3 Vektoren nehmen wollen (AFAIK dot() ist nicht für int3 s überlastet), so dass anstelle von dot() von mir in unvectorized Art und Weise der Umsetzung, möchte ich mithilfe der den Code vektorisieren nativ dot() für float3. Zuerst konvertiere ich die 2 Vektoren in float3 s und dann werfe ich das Ergebnis auf int.

Welche der beiden Funktionen, foo und bar, ist weniger zeitaufwendig (und warum)?

inline int foo(int3 a, int3 b) { 
    return a.x*b.x + a.y*b.y + a.z*b.z; 
} 

inline int bar(int3 a, int3 b) { 
    return (int)dot(convert_float3(a), convert_float3(b)); 
} 
+0

Erste Regel der Optimierung: messen. Zweite Regel der Optimierung: erneut messen. Dies ist vollständig von Hardware und Architektur abhängig. Niemand kann eine definitive Antwort auf Ihre Frage geben. –

+0

@AndreasPapadopoulos Ich stimme zu. Übrigens, wissen Sie etwas über eine genauere Art der Profilerstellung - d. H. Die Ausführungszeit für jeden einzelnen Befehl des Kernels (etwas wie Apples Metal) zu sehen, anstatt nur die Ausführungszeit des * ganzen * Kernels zu sehen? – sarasvati

+0

@AndreasPapadopoulos, um die Idee besser zu veranschaulichen, werfen Sie einen Blick auf [dieses Profiling-Sitzungsbild] (https://developer.apple.com/library/ios/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/Art/xcode_gpu_overview_program_2x.png) in XCode . Es zeigt den prozentualen Zeitaufwand für jede Codezeile an. – sarasvati

Antwort

1

Wie in den Kommentaren vorgeschlagen, Mess wird das nützlichste Instrument in der Praxis sein, und die Kosten für die einzelnen Befehle sind auf Hardware-Architektur stark abhängig, sondern auch die Compiler.

Dennoch ist ein Vergleich zu anderen Operationen nützlich, und AMD veröffentlicht zumindest eine Liste des Befehlsdurchsatzes für ihre Geräte in this section of their OpenCL optimisation guide, und dies umfasst Float-Int-und Int-Float-Konvertierung.

In Ihrem speziellen Fall vermute ich stark, dass Ihre "vektorisierenden" Versuche schädliche Auswirkungen haben werden. Die meisten modernen GPUs sind keine SIMD-Prozessoren in der CPU-SIMD-Richtung. Die Threads laufen in Lock-Step, aber jeder Thread arbeitet mit Skalaren. Eine "horizontale" Operation wie ein Skalarprodukt ist möglicherweise nicht besonders effizient, selbst wenn die GPU pro Thread SIMD verwendet.

Wenn Sie den Bereich jeder Ihrer Ganzzahlen auf 24 Bit begrenzen können, ist eine Reihe von Aufrufen mad24() und mul24() wahrscheinlich am schnellsten. Aber nochmal - messen. Probieren Sie die verschiedenen Optionen auf einer Reihe von Hardware aus und führen Sie sie viele Male aus, indem Sie grundlegende Statistiken anwenden, um sicherzustellen, dass Sie nicht nur zufällige Variationen/Overhead sehen.

Eine separate Sache, die in Bezug auf Integer-Float-Konvertierungen zu beachten ist, ist, dass solche Konvertierungen oft "frei" sind, wenn Sie als Float-Werte von einem Bildobjekt mit Ganzzahlen abtasten.