Warum läuft das Renderscript-Beispiel für die Google-Bildverarbeitung auf der GPU in Nexus 5 langsamer?
Ich möchte Stephen für die sehr schnelle Antwort in einem früheren Beitrag danken. Dies ist eine Folgefrage für diesen BeitragWarum sehr einfach Renderscript läuft in der GPU 3 mal langsamer als in der CPU
Meine Entwicklerplattform ist wie folgt
Development OS: Windows 7 32-bit
Phone: Nexus 5
Phone OS version: Android 4.4
SDK bundle: adt-bundle-windows-x86-20131030
Build-tool version: 19
SDK tool version: 22.3
Platform tool version: 19
Um die Leistung der Renderscript-GPU-Berechnung zu bewerten und den allgemeinen Trick zu verstehen, mit dem Code durch Renderscript schneller gemacht werden kann, habe ich den folgenden Test durchgeführt.
Ich habe den Code aus Googles Android Open Source-Projekt mit dem Tag android-4.2.2_r1.2 ausgecheckt. Ich habe dieses Tag einfach verwendet, weil das ImageProcessing-Testbeispiel in der neueren Version nicht verfügbar ist.
Dann habe ich das Projekt unter "base \ tests \ RenderScriptTests \ ImageProcessing" im Test verwendet. Ich habe die Leistung beim Ausführen von Code auf der GPU sowie auf der CPU aufgezeichnet. Die Leistung ist unten aufgeführt.
GPU CPU
Levels Vec3 Relaxed 7.45ms 14.89ms
Levels Vec4 Relaxed 6.04ms 12.85ms
Levels Vec3 Full N/A 28.97ms
Levels Vec4 Full N/A 35.65ml
Blur radius 25 203.2ms 245.60ms
Greyscale 7.16ms 11.54ms
Grain 33.33ms 21.73ms
Fisheye Full N/A 51.55ms
Fisheye Relaxed 92.90ms 45.34ms
Fisheye Approx Full N/A 51.65ms
Fisheye Approx Relaxed 93.09ms 39.11ms
Vignette Full N/A 44.17ms
Vignette Relaxed 8.02ms 46.68ms
Vignette Approx Full N/A 45.04ms
Vignette Approx Relaxed 8.20ms 43.69ms
Convolve 3x3 37.66ms 16.81ms
Convolve 3x3 Intrinsics N/A 4.57ms
ColorMatrix 5.87ms 8.26ms
ColorMatrix Intrinsics N/A 2.70ms
ColorMatrix Intinsics Grey N/A 2.52ms
Copy 5.59ms 2.40ms
CrossProcess(using LUT) N/A 5.74ms
Convolve 5x5 84.25ms 46.59ms
Convolve 5x5 Intrinsics N/A 9.69ms
Mandelbrot N/A 50.2ms
Blend Intrinsics N/A 21.80ms
Die N / A in der Tabelle werden entweder durch die volle Genauigkeit verursacht, oder die intrinsische Funktion wird auf der GPU nicht ausgeführt. Wir können sehen, dass unter 13 Algorithmen, die auf einer GPU ausgeführt werden, 6 auf einer GPU langsamer ausgeführt werden. Da ein solcher Code von Google geschrieben wurde, halte ich dieses Phänomen für etwas untersuchenswert. Zumindest "Ich gehe davon aus, dass der Code auf der GPU schneller läuft", wie ich gesehen habeRenderscript und die GPU hält hier nicht.
Ich habe einige der Algorithmen in der Liste untersucht, ich möchte zwei erwähnen.
In Vignette ist die Leistung auf der GPU viel besser, ich fand, dass dies durch Aufrufen mehrerer Funktionen in rs_cl.rsh verwendet wurde. Wenn ich diese Funktionen auskommentiere, läuft die CPU schneller (siehe meine vorherige Frage oben für einen Extremfall). Die Frage ist also, warum dies passiert. In rs_cl.rsh sind die meisten Funktionen mathematikbezogen, z. exp, log, cos, etc. Warum läuft eine solche Funktion auf der GPU viel schneller? Liegt das daran, dass die Implementierung dieser Funktionen tatsächlich hoch parallel ist oder nur daran, dass die Implementierung der Version auf der GPU besser ist als die Version auf der CPU?
Ein anderes Beispiel ist conv3x3 und conv5x5. Zwar gibt es in dieser Test-App eine andere clevere Implementierung als Googles Version, aber ich denke, diese Implementierung von Google ist mit Sicherheit nicht schlecht. Es versucht, die Additionsoperation zu minimieren, und verwendet eine Erleichterungsfunktion aus rs_cl.rsh wie convert_float4 (). Auf den ersten Blick gehe ich davon aus, dass es auf der GPU schneller läuft. Es läuft jedoch viel langsamer (auf Nexus 4 und 5, die beide die GPU von Qualcomm verwenden). Ich halte dieses Beispiel für sehr repräsentativ, da der Algorithmus in der Implementierung auf die Pixel in der Nähe des aktuellen Pixels zugreifen muss. Eine solche Operation ist bei vielen Bildverarbeitungsalgorithmen ziemlich verbreitet. Wenn die Implementierung wie 2D-Faltung in der GPU nicht schneller gemacht werden kann, gibt es vermutlich viele andere Algorithmen, die das gleiche leiden würden. Es wäre sehr dankbar, wenn Sie das Problem identifizieren und einige Möglichkeiten vorschlagen könnten, um solche Algorithmen schneller zu machen.
Die allgemeinere Frage ist, angesichts des Testergebnisses, das ich gezeigt habe, möchte ich fragen, welche Kriterien Menschen befolgen sollten, um die höhere Leistung zu erzielen und die Leistungsverschlechterung so weit wie möglich zu vermeiden. Schließlich ist das Leistungsziel das zweitwichtigste Ziel von Renderscript, und ich denke, die Portabilität von RS ist recht gut.
Vielen Dank!