(Vec4 x Mat4x4) Produkt mit SIMD und Verbesserungen

8

Ich schreibe ein komplexes Simulationsprogramm und es ist offensichtlich, dass die zeitaufwendigste Routine diejenige ist, die einen Vier-Vektor (float4) mit einer 4x4-Matrix multipliziert. Ich muss dieses Programm auf mehreren Computern ausführen, die mehr oder weniger alt sind. Aus diesem Grund habe ich im folgenden Code versucht, SIMD-Fähigkeiten solcher Operationen zu überprüfen:

%Vor%

Ich habe einige Probleme mit den Verbesserungen für ein solches Problem. Wenn ich den Code ausführe, erhalte ich die folgenden Ergebnisse (Intel Core i5 4670K, 3.4GHz, Haswell, Codeblock + MinGW Compiler mit -O2-march = corei7-avx):

%Vor%

Meine Fragen sind die folgenden:

  1. Ist es möglich, die Leistungen zu verbessern / zu beschleunigen? Es sollte sein x4 (maximal) für SSE und x8 für AVX.

  2. Warum ist AVX nicht schneller als SSE3?

Für diejenigen, die sagen: "Hör auf, deine Sachen zu verwenden, benutze Intel Math Kernel Library", antworte ich: "Ich würde nicht, weil ich eine kleine ausführbare Datei möchte, und ich brauche nur SIMD für diesen speziellen Fall, nicht woanders "; -)

    
Asohan 26.06.2015, 15:01
quelle

1 Antwort

5
  

Ist es möglich, die Leistung zu verbessern / zu beschleunigen? Es sollte x4 (maximal) für SSE und x8 für AVX sein.

Ja, ich habe das im Detail unter effizient-4x4-Matrix-Vektor-Multiplikation-mit-sse-horizontal-Add-and-dot-Produkt .

Die effiziente Methode zum Multiplizieren einer 4x4-Matrix M mit einem Spaltenvektor u mit v = M u ist:

%Vor%

Dies erfordert, dass Sie die Spaltenvektoren speichern. Angenommen, Sie haben die folgende 4x4-Matrix A :

%Vor%

dann speichern Sie dies als

%Vor%

umgekehrt, wenn Sie möchten, Zeilenvektor uT mal Matrix M geben vT = uT*M dann möchten Sie

%Vor%

und in diesem Fall sollten Sie die Zeilen nicht die Spalten packen.

Um also Ihren Code in Ihrer Funktion A_times_x_SSE zu optimieren, kommentieren Sie die Zeile

aus %Vor%

und diese Funktion ist schneller als Ihre anderen Funktionen mit horizontalen Operationen.

Horizontale Operationen mit SIMD sind nicht effizient. Sie sind in einigen seit nicht SIMD, weil sie in skalare Mikro-Ops unterteilt sind, so dass sie nicht parallel sind. Sie sind nur nützlich, wenn es ungünstig ist, Ihre Daten in einem SIMD-freundlichen Format zu packen. Zum Beispiel, wenn Sie die Spalten von M nicht speichern können und nur die Zeilen haben.

  

Warum ist der AVX nicht schneller als SSE3?

Um dies effizient mit AVX zu tun, müssen Sie auf zwei 4x4-Matrizen auf einmal arbeiten und auch Matrizen verpacken, damit sie für AVX freundlich sind. Nun nehmen wir an, dass zusätzlich die oben definierte Matrix A eine andere Matrix B hat:

%Vor%

Der optimale Weg, um A und B für AVX zu packen, ist

%Vor%

Nehmen wir an, Sie haben zwei Vektoren u = {0,1,2,3} und v = {4,5,6,7) und Sie wollen y = Au und z = Bv dann mit AVX tun Sie:

%Vor%

Der resultierende 8-wide Vektor w enthält also die 4-Vektoren y und z . Dies ist die effizienteste Methode mit AVX. Wenn Sie feste Matrizen und variable Vektoren haben, können Sie in einer Schleife überfahren und dann packen, bevor die Schleife zur Laufzeit für eine große Schleife vernachlässigbar ist. Wenn Sie wissen, dass die Matrizen zur Kompilierungszeit festgelegt sind, können Sie zur Kompilierungszeit packen.

    
Z boson 27.06.2015, 22:12
quelle

Tags und Links