Optimaler SIMD-Algorithmus zum Rotieren oder Transponieren eines Arrays

8

Ich arbeite an einer Datenstruktur, wo ich ein Array von 16 Uint64 habe. Sie sind so im Speicher angeordnet (jede unten repräsentiert ein einzelnes int64):

%Vor%

Das gewünschte Ergebnis ist, das Array in dieses zu transponieren:

%Vor%

Die Drehung des Arrays um 90 Grad ist auch eine akzeptable Lösung für die zukünftige Schleife:

%Vor%

Ich brauche das, um den Pfeil zu einem späteren Zeitpunkt schnell zu bearbeiten (traversiere ihn sequentiell mit einem weiteren SIMD-Trip, 4 gleichzeitig).

Bisher habe ich versucht, die Daten zu "mixen", indem ich einen 4 x 64-Bit-Vektor von A's hochlade, die Elemente maskierte und mischte und sie mit B's OR-verknüpfte und dann für C's wiederholte ... Leider Dies sind 5 x 4 SIMD-Befehle pro Segment von 4 Elementen im Array (ein Laden, eine Maske, ein Shuffle, ein oder mit dem nächsten Element und schließlich ein Speicher). Es scheint, ich sollte es besser machen können.

Ich habe AVX2 verfügbar und ich kompiliere mit clang.

    
Thomas Kejser 19.11.2014, 09:32
quelle

2 Antworten

10
%Vor%

Ich habe keine Hardware, um dies jetzt zu testen, aber etwas wie das Folgende sollte tun, was Sie wollen

%Vor%

Das

%Vor%

intrinsisch wählt 128-Bit-Spuren aus zwei Quellen aus. Sie können darüber im Intel Intrinsic Guide nachlesen. Es gibt eine Version _mm256_permute2f128_si256 , die nur AVX benötigt und in der Floating-Point-Domäne agiert. Ich habe das verwendet, um zu überprüfen, ob ich die richtigen Steuerwörter verwendet habe.

    
Z boson 19.11.2014, 10:28
quelle
4

Eine Alternative ist die Verwendung der sammeln Anweisungen, Sie können die transponierte Matrix direkt laden. Die fünf Zeilen Code unten sind ok mit gcc auf einem i7-Haswell.

%Vor%     
user3636086 20.11.2014 10:21
quelle

Tags und Links