4 horizontale Doppelpräzisionssummen auf einmal mit AVX

8

Das Problem kann wie folgt beschrieben werden.

Eingabe

%Vor%

Ausgabe

%Vor%

Arbeit, die ich bisher gemacht habe

Es schien einfach zu sein: Zwei VHADDs mit einigen Zwischenmischungen, die aber alle Permutationen von AVX kombinieren, können nicht genau die Permutation erzeugen, die nötig ist, um dieses Ziel zu erreichen. Lassen Sie mich erklären:

%Vor%

Konnte ich x und y auf die gleiche Weise permutieren, um

zu erhalten? %Vor%

dann

%Vor%

Welches ist das Ergebnis, das ich wollte.

Also muss ich nur herausfinden, wie man

ausführt %Vor%

Leider kam ich zu dem Schluss, dass dies nachweislich unmöglich ist, wenn eine Kombination von VSHUFPD, VBLENDPD, VPERMILPD, VPERM2F128, VUNPCKHPD, VUNPCKLPD verwendet wird. Der Kern der Sache ist, dass es unmöglich ist, u [1] und u [2] in einem Fall u von __m256d zu tauschen.

Frage

Ist das wirklich eine Sackgasse? Oder habe ich eine Permutationsanweisung verpasst?

    
Paul R 31.05.2012, 12:03
quelle

2 Antworten

6
Den Anweisungen von

VHADD folgt regelmäßig VADD . Der folgende Code sollte Ihnen geben, was Sie wollen:

%Vor%

Dies ergibt das Ergebnis in 5 Anweisungen. Ich hoffe, ich habe die Konstanten richtig verstanden.

Die Permutation, die Sie vorgeschlagen haben, ist sicherlich möglich, aber es erfordert mehrere Anweisungen. Entschuldigung, dass ich diesen Teil Ihrer Frage nicht beantworte.

Edit: Ich konnte nicht widerstehen, hier ist die komplette Permutation. (Wiederum habe ich versucht, die Konstanten richtig zu machen.) Sie können sehen, dass das Tauschen von u[1] und u[2] möglich ist, dauert nur ein wenig Arbeit. Das Überqueren der 128-Bit-Grenze ist in der ersten Generation schwierig. AVX. Ich möchte auch sagen, dass VADD gegenüber VHADD vorzuziehen ist, weil VADD den doppelten Durchsatz hat, obwohl es die gleiche Anzahl von Additionen durchführt.

%Vor%     
Norbert P. 31.05.2012, 14:27
quelle
1

Mir ist keine Anweisung bekannt, mit der Sie diese Art von Permutation durchführen können. AVX-Befehle arbeiten typischerweise so, dass die oberen und unteren 128 Bits des Registers etwas unabhängig sind; es gibt nicht viel Fähigkeit, Werte von den zwei Hälften zu mischen. Die beste Implementierung, die ich mir vorstellen kann, würde auf der Antwort auf diese Frage :

%Vor%

Was sollte was du willst. Das obige sollte in 7 Gesamtanweisungen machbar sein (die Umwandlung sollte nicht wirklich etwas bewirken; es ist nur eine Anmerkung für den Compiler, die Art der Behandlung des Wertes in res1 zu ändern), vorausgesetzt, dass die kurze horizontal_add_pd() -Funktion sein kann Inline von Ihrem Compiler und Sie haben genügend Register zur Verfügung.

    
Jason R 31.05.2012 12:53
quelle

Tags und Links