Ich versuche eine Bildformatkonvertierung unter iOS mit dem NEON-Vektor-Befehlssatz zu optimieren. Ich nahm an, dies würde gut darauf abbilden, weil es eine Menge ähnlicher Daten verarbeitet.
Meine Versuche sind jedoch nicht so gut gelaufen und haben nur eine marginale Beschleunigung gegenüber der naiven c-Implementierung erreicht:
%Vor%1 Megapixel-Bild-Array auf iPad 2:
Das Formatist [min avg max n = Anzahl der Timer-Samples] in Millisekunden
C: [14.446 14.632 18.405 n = 1000] ms
NEON: [11.920 12.032 15.336 n = 1000] ms
Mein Versuch einer NEON-Implementierung ist unten:
%Vor%Code wurde über LLVM 3.0 in das folgende kompiliert (.loc und extra Etiketten entfernt):
%Vor%Der vollständige Code ist verfügbar unter Ссылка Ich würde mich über jede Hilfe freuen, danke!
Hier sind Sie, Hand-optimierte NEON-Implementierung bereit für XCode:
%Vor%Diese Version wird um ein Vielfaches schneller sein als das, was Sie vorgeschlagen haben:
erhöhte Cache-Trefferrate über PLD
Umwandlung in "lang" nicht notwendig
weniger Anweisungen innerhalb der Schleife
Es gibt jedoch noch etwas Spielraum für Optimierungen. Sie könnten die Schleife so ändern, dass sie 16 Pixel pro Iteration anstelle von 8 konvertiert. Dann können Sie die Anweisungen einplanen, um die zwei Stops vollständig zu vermeiden (was in dieser 8 / Iteration-Version oben nicht möglich ist) und zusätzlich von NEONs Dual-Issue-Fähigkeit profitieren.
Ich habe das nicht gemacht, weil es den Code schwer verständlich machen würde.
Es ist wichtig zu wissen, was VEXT machen soll.
Jetzt liegt es an dir. :)
Ich habe überprüft, dass dieser Code unter Xcode korrekt kompiliert wurde. Obwohl ich mir sicher bin, dass es auch richtig funktioniert, kann ich das nicht garantieren, da ich die Testumgebung nicht habe. Im Falle einer Fehlfunktion, lass es mich wissen. Ich werde es dann entsprechend korrigieren.
cya
================================================== ================================
Nun, hier ist die verbesserte Version.
Da der VSRI-Befehl zwei Operanden außer dem Ziel nicht zulässt, war es nicht möglich, einen robusteren bezüglich der Registerzuweisung zu erstellen.
Bitte überprüfen Sie das Bildformat Ihres Quellbildes. (exakte Byte-Reihenfolge der Elemente)
Wenn es sich nicht um B, G, R, A handelt, das standardmäßig und nativ für iOS ist, wird Ihre Anwendung stark von internen Konvertierungen von iOS betroffen sein.
Wenn es absolut nicht möglich ist, dies aus irgendeinem Grund zu ändern, lassen Sie es mich wissen. Ich schreibe eine neue Version passend dazu.
PS: Ich habe vergessen, den Unterstrich am Anfang des Funktionsprototyps zu entfernen. Jetzt ist es weg.
%Vor%Wenn Sie auf iOS oder OS X arbeiten, sind Sie möglicherweise erfreut, vImageConvert_RGBA8888toRGB565 () und Freunde in Accelerate.framework zu entdecken. Diese Funktion rundet die 8-Bit-Werte auf den nächsten Wert von 565 auf.
Für ein noch besseres Dithering, dessen Qualität fast nicht von einer 8-Bit-Farbe zu unterscheiden ist, versuchen Sie es mit vImageConvert_AnyToAny ():
%Vor%Einer dieser Ansätze wird für die beste Leistung vektorisiert und mit mehreren Threads versehen.
(Ich bin nicht vertraut mit NEON, noch zutiefst mit dem Speichersystem des Ipad2, aber das ist, was wir früher mit 88110 Pixel-Ops gemacht haben, die ein früher Vorläufer der heutigen SIMD-Erweiterungen waren)
Wie groß ist die Speicherlatenz?
Können Sie es verbergen, indem Sie die innere Schleife abrollen und die NEON-Anweisungen auf den "vorherigen" Werten ausführen, während der ARM die "nächsten" Werte aus dem Speicher zieht? Ein kurzer Scan des NEON-Handbuchs bedeutet, dass Sie ARM- und NEON-Anweisungen parallel ausführen können.
Ich glaube nicht, dass die Konvertierung von vld4_u8 in vld4q_u8 zu einer Verbesserung der Performance führen würde.
Der Code scheint einfach genug zu sein. Ich bin nicht gut in ASM und so würde es einige Zeit dauern, um es tief zu untersuchen.
Das Neon scheint einfach genug zu sein. Aber ich bin nicht sicher, ob r5_g6_b5 | = g16 anstelle von vorrq_u16
verwendet wirdSehen Sie sich auch die Optimierungsstufe an. Was den Wert der Neon-Code-Optimierung betrifft, so wird dieser auf maximal 1 gesetzt. Die Leistung kann daher abweichen, wenn die Standard-Optimierung sowohl für den Referenzcode als auch für den Neon-Code berücksichtigt wird anders.
Ich finde keinen Bereich in Neon, der den aktuellen Code verbessern könnte.