Ich optimiere eine elementweise Multiplikation zweier eindimensionaler Arrays für einen dualen Cortex-A9-Prozessor. Linux läuft auf dem Board und ich verwende den GCC 4.5.2 Compiler.
Das Folgende ist meine C ++ Inline-Assembler-Funktion. src1, src2 und dst sind 16 Byte ausgerichtet.
Update: Testbarer Code:
%Vor%Die Berechnung von 1024 * 1024 Werten dauert ~ 0,016 s. (Zwei Threads - jeder Thread berechnet eine Hälfte des Arrays). Naiv interpretiert, benötigt die Berechnung einer Iteration 122 Zyklen. Dies scheint ein bisschen langsam zu sein. Aber wo ist der Flaschenhals?
Ich probierte sogar den Befehl pld
, um Elemente im L2-Cache vorzuladen, indem ich die Schleife abrollte, indem ich bis zu 20 Werte pro Iteration berechnete und die Befehle neu ordnete, damit der Prozessor nicht auf Speicher wartete. Ich habe nicht so viel Beschleunigung (max. 0,001 s schneller).
Haben Sie Vorschläge zur Beschleunigung der Berechnung?
Ich weiß nicht viel über den NEON. Ich denke jedoch, dass Datenabhängigkeiten Leistungsprobleme verursachen. Ich würde vorschlagen, dass Sie die Schleife mit einigen Ladungen primieren und dann zwischen dem multiplizieren und speichern platzieren. Ich denke, der Speicher blockiert wahrscheinlich, bis die Multiplikation abgeschlossen ist.
%Vor%Auf diese Weise sollten Sie in der Lage sein, die Lasten mit der Multiplikation parallel zu führen. Sie müssen die Quell-Arrays überzuordnen oder ändern Sie den Loop-Index und eine abschließende Multiplikation und speichern. Wenn sich die NEON-Ops nicht auf die Bedingungscodes auswirken, können Sie die Subs ebenfalls neu ordnen und sie früher platzieren.
Bearbeiten: Tatsächlich empfiehlt das Dokument Cortex A-9 Media-Verarbeitungsmodul , ARM- und NEON-Befehle zu verschachteln, da sie parallel ausgeführt werden können. Außerdem scheinen die NEON-Anweisungen FPSCR und nicht die ARM CPSR zu setzen, so dass die Neuordnung der subs
die Ausführungszeit verringern würde. Sie können die Schleife auch cachen ausrichten.
Tags und Links optimization c++ assembly arm neon