Effiziente Methode, um die ersten N oder letzten N Bits von __m256i auf 1 zu setzen, der Rest auf 0

8

Wie Sie mit AVX2 auf 1 effizient einstellen können

  1. erste N Bits
  2. letzte N Bits

von __m256i , den Rest auf 0 setzen?

Dies sind zwei separate Operationen für Tail und Kopf eines Bitbereichs, wenn der Bereich in der Mitte von __m256i -Wert beginnen und enden darf. Der Teil des Bereichs, der die vollen __m256i -Werte belegt, wird mit allen% % 0 oder allen% %%% masken verarbeitet.

    
Serge Rogatch 03.09.2017, 15:16
quelle

1 Antwort

9

Die AVX2-Shift-Anweisungen vpsllvd und vpsrlvd haben die nette Eigenschaft, dass Shift zählt größer als oder gleich 32 führen zu Null-Ganzzahlen innerhalb des Ymm-Registers. Mit anderen Worten: Die Shift-Counts sind demgegenüber nicht maskiert zu der Verschiebung zählt für die x86-Skalar-Shift-Anweisungen.

Daher ist der Code ziemlich einfach:

%Vor%

Die Ergebnisse sind:

%Vor%

Für einen Wert n , mit 256 & lt; = n & lt; = 65535 werden alle Bits wie erwartet auf eins gesetzt. Die Obergrenze von 65535 ist auf die 16-Bit-Sättigungsarithmetik von _mm256_subs_epu16() zurückzuführen. Mit n = 65536 ist die Bitmaske (der Ausgabewert) gleich Null. Es ist möglich, den Code so zu ändern, dass alle Bits auf Eins gesetzt werden für den Bereich von 256 & lt; = n & lt; = INT_MAX . Dies kann durch Ersetzen erreicht werden shift = _mm256_subs_epu16(cnst32_256,shift); mit

%Vor%

Diese drei Eigenarten emulieren mehr oder weniger _mm256_subs_epu32(cnst32_256,shift) , was nicht existiert.

    
wim 03.09.2017, 18:58
quelle