Schnelles Zählen der Anzahl der gesetzten Bits im __m128i-Register

8

Ich sollte die Anzahl der gesetzten Bits eines __m128i-Registers zählen. Insbesondere sollte ich zwei Funktionen schreiben, die in der Lage sind, die Anzahl der Bits des Registers auf folgende Weise zu zählen.

  1. Die Gesamtzahl der gesetzten Bits des Registers.
  2. Die Anzahl der gesetzten Bits für jedes Byte des Registers.

Gibt es intrinsische Funktionen, die die obigen Operationen ganz oder teilweise ausführen können?

    
enzom83 27.06.2013, 23:37
quelle

4 Antworten

21

Hier sind einige Codes, die ich in einem alten Projekt verwendet habe ( es gibt ein Forschungspapier darüber ) . Die Funktion popcnt8 unter berechnet die Anzahl der in jedem Byte gesetzten Bits.

SSE2-only Version (basierend auf Algorithmus 3 in Hacker's Delight Buch ):

%Vor%

SSSE3-Version (wegen Wojciech Mula ):

%Vor%

XOP-Version (entspricht SSSE3, verwendet aber XOP-Anweisungen, die auf dem AMD Bulldozer schneller sind)

%Vor%

Die Funktion popcnt64 unten zählt die Anzahl der Bits in den unteren und oberen 64-Bit-Teilen des SSE-Registers:

SSE2-Version:

%Vor%

XOP-Version:

%Vor%

Schließlich zählt die folgende Funktion popcnt128 die Anzahl der Bits im gesamten 128-Bit-Register:

%Vor%

Eine effizientere Methode zur Implementierung von popcnt128 ist jedoch die Verwendung der Hardware-POPCNT-Anweisung (auf Prozessoren, die dies unterstützen):

%Vor%     
Marat Dukhan 28.06.2013, 00:21
quelle
1

Hier ist eine Version basiert auf Bit Twiddling Hacks - Zählen Bits parallel setzen mit ähnlichen Namen zu anderen intrinsischen Funktionen sowie einige zusätzliche Funktionen für 16 32 und 64-Bit-Vektoren

%Vor%     
technosaurus 01.02.2018 17:04
quelle
0

Wie bereits im ersten Kommentar erwähnt, bietet gcc 3.4+ einen einfachen Zugang zu einem (hoffentlich optimalen) eingebauten

%Vor%

Wie hier gesagt: Ссылка

Beantwortet die Frage nicht genau für 128Bits, sondern gibt eine nette Antwort auf die Frage, die ich hatte, als ich hier landete:)

    
yota 29.04.2014 15:19
quelle
-2

Edit: Ich glaube, ich habe nicht verstanden, wonach das OP gesucht hat, aber ich halte meine Antwort für den Fall auf, dass es für jeden nützlich ist, der darüber stolpert.

C bietet einige schöne bitweise Operationen.

Hier ist Code, um die Anzahl der in einer Ganzzahl gesetzten Bits zu zählen:

%Vor%

Erläuterung:

%Vor%

Gibt das letzte Bit in unserer Ganzzahl zurück. (Durch Division durch zwei und Überprüfung des Rests). Wir fügen dies zu unserer Gesamtanzahl hinzu und verschieben dann die Bits unseres toCount-Werts um eins. Diese Operation sollte fortgesetzt werden, bis keine weiteren Bits in toCount gesetzt sind (wenn toCount gleich 0 ist)

Um die Anzahl der Bits in einem bestimmten Byte zu zählen, sollten Sie eine Maske verwenden. Hier ist ein Beispiel:

%Vor%

Nehmen wir an, dass wir in unserem System Byte 0 als das niedrigstwertige Byte in einem kleinen Endian-System betrachten. Wir wollen einen neuen toCount erstellen, der an unsere frühere countBitsSet-Funktion übergeben wird, indem wir die auf 0 gesetzten Bits maskieren. Dazu verschieben wir ein Byte voll von Einsen (bezeichnet mit dem Buchstaben F) an die gewünschte Position (byteNumber *). 8 für 8 Bits in einem Byte) und führt eine bitweise UND-Operation mit unserer toCount-Variable durch.

    
Perfect Tommy 28.06.2013 00:11
quelle

Tags und Links