fehlt NICHT in SSE, AVX?

8

Ist es meine Einbildung, oder fehlt eine Anweisung PNOT von SSE und AVX? Das heißt, eine Anweisung, die jedes Bit im Vektor umlegt.

Wenn ja, gibt es eine bessere Möglichkeit, es als PXOR mit einem Vektor aller 1s zu emulieren? Ziemlich nervig, da ich einen Vektor aller 1s einrichten muss, um diesen Ansatz zu verwenden.

    
SODIMM 05.03.2017, 20:50
quelle

4 Antworten

9

In solchen Fällen kann es hilfreich sein zu sehen, was ein Compiler erzeugen würde.

z. für die folgende Funktion:

%Vor%

Sowohl gcc als auch clang scheinen viel denselben Code zu generieren :

%Vor%     
Paul R 06.03.2017, 08:54
quelle
4

Wenn Sie Intrinsics verwenden, können Sie eine Inline-Funktion wie diese verwenden, um die nicht-Operation separat zu haben.

%Vor%     
Martin 06.03.2017 01:30
quelle
3

Sie können dafür den PANDN OpCode verwenden.

PANDN implementiert die Operation

%Vor%

oder

%Vor%

Die Kombination dieser Operation mit einem All-Einsen-Vektor führt effektiv zu einer PNOT -Operation.

Einige x86 (SSEx) Assembly-Code würde wie folgt aussehen:

%Vor%

Einige x86 (AVXx) Assembly-Code würde wie folgt aussehen:

%Vor%

Beide können (natürlich) leicht in intrinsisch übersetzt werden.

    
zx485 06.03.2017 21:46
quelle
2

AVX512F vpternlogd / _mm512_ternarylogic_epi32(__m512i a, __m512i b, __m512i c, int imm8) bietet schließlich eine Möglichkeit, NOT ohne zusätzliche Konstanten zu implementieren, indem eine einzige Anweisung verwendet wird (mit 2 pro Takt Durchsatz auf Skylake-avx512 und KNL, also ist es nicht so gut wie PXOR / XORPS für 256b und kleinere Vektoren. )

vpternlogd zmm,zmm,zmm, imm8 hat 3 Eingabevektoren und einen Ausgang, um das Ziel an Ort und Stelle zu ändern. Mit der richtigen sofortigen, können Sie immer noch eine Kopie-und-NOT in ein anderes Register implementieren, aber es wird eine "falsche" Abhängigkeit von der Ausgabe-Register (die vpxord dst, src, all-ones hätte nicht).

TL: DR: benutze wahrscheinlich immer noch xor mit All-Einsen als Teil einer Schleife, außer wenn dir die Register ausgehen. vpternlog kann einen zusätzlichen vmovdqa register-copy-Befehl kosten, wenn seine Eingabe später benötigt wird. Außerhalb von Schleifen ist vpternlogd zmm,zmm,zmm, 0xff Compiler beste Option für die Erstellung eines 512b All-One-Vektors an erster Stelle , da AVX512-Vergleiche Anweisungen in Masken vergleichen ( k0-k7 ), so dass XOR mit All-Einsen möglicherweise bereits einen vpternlogd oder vielleicht ein Broadcast-Konstante aus dem Speicher.

Für jede Bitposition i ist das Ausgabe-Bit imm[ (DEST[i]<<2) + (SRC1[i]<<1) + SRC2[i]] , wobei imm8 als Bitmap mit 8 Elementen behandelt wird.

Wenn wir also wollen, dass das Ergebnis nur von SRC2 abhängt (was der zmm/m512/m32bcst -Operand ist), sollten wir eine Bitmap wählen, die 1,0 wiederholt, mit 1 an den geraden Positionen (ausgewählt von src2=0 ).

%Vor%

Wenn Sie Glück haben, wird ein Compiler _mm512_xor_epi32(v, set1(-1)) auf vpternlogd für Sie optimieren, wenn es profitabel ist.

%Vor%

Wenn Sie nicht sicher sind, ob das eine gute Idee ist, halten Sie es einfach und verwenden Sie die gleiche Variable für alle 3 Eingaben:

%Vor%     
Peter Cordes 18.09.2017 07:11
quelle

Tags und Links