Was ist die Implementierung von GCCs (4.6+) __builtin_clz
? Entspricht es einer CPU-Anweisung auf Intel x86_64 (AVX)
?
Implementierung von __builtin_clz
Ja und nein.
CLZ (Count Leading Zero) und BSR (Bit-Scan Reverse) sind verwandt, aber unterschiedlich. CLZ ist gleich (Typbitbreite weniger eins) – BSR. CTZ (Count Trailing Zero), auch bekannt als FFS (Find First Set) ist dasselbe wie BSF (Bit-Scan Forward).
Beachten Sie, dass all diese beim Betrieb auf Null undefiniert sind!
Als Antwort auf Ihre Frage generiert __builtin_clz die meiste Zeit auf x86 und x86_64 eine BSR-Operation, die von 31 (oder was auch immer Ihre Typbreite ist) subtrahiert wird, und __builting_ctz generiert eine BSF-Operation.
Wenn Sie wissen wollen, was Assembler GCC generiert, ist der beste Weg, es zu wissen, es zu sehen. Das Flag -S lässt gcc den Assembler ausgeben, den es für die gegebene Eingabe generiert hat:
gcc -S -o test.S test.c
In Betracht ziehen:
unsigned int clz(unsigned int num) {
return __builtin_clz(num);
}
unsigned int ctz(unsigned int num) {
return __builtin_ctz(num);
}
Auf x86 für clz generiert gcc (-O2):
bsrl %edi, %eax
xorl $31, %eax
ret
und für ctz:
bsfl %edi, %eax
ret
Beachten Sie, dass Sie, wenn Sie wirklich bsr und nicht clz wollen, 31 – clz (für 32-Bit-Ganzzahlen) ausführen müssen. Dies erklärt das XOR 31 als x XOR 31 == 31 – x (diese Identität gilt nur für Zahlen der von 2^y – 1) Also:
num = __builtin_clz(num) ^ 31;
Erträge
bsrl %edi, %eax
ret
Chisophugis
Es sollte zu a übersetzen Bit-Scan-Umkehrung Anweisung und eine Subtraktion. Der BSR gibt den Index der führenden 1 an, den Sie dann von der Wortgröße subtrahieren können, um die Anzahl der führenden Nullen zu erhalten.
Bearbeiten: Wenn Ihre CPU LZCNT (Leading Zero Count) unterstützt, reicht das wahrscheinlich auch aus, aber nicht alle x86-64-Chips haben diese Anweisung.
-
Anscheinend ist der Link kaputt.
– Marsmensch
23. Mai 2018 um 3:38 Uhr
-
Link sollte jetzt behoben sein.
– Chisophugis
7. Juli 2018 um 5:18 Uhr
-
Wenn Sie Compiler mit
-mbmi1
das sagst du gcclzcnt
ist auf allen CPUs verfügbar, die diese Binärdatei ausführen. (oder viel besser-march=haswell
oder-march=bdver2
oder-march=znver1
oder was auch immer, um auf eine bestimmte CPU abzustimmen und Befehlssätze zu aktivieren.)– Peter Cordes
7. Juli 2018 um 5:34 Uhr
-
Warum bietet gcc
__builtin_clz
aber nicht bit scan reverse?– theonlygusti
28. März 2021 um 13:17 Uhr
-
godbolt.org/z/5re8vWzq8 ja, je nach Befehlssatz werden beide generiert
– sehen
2. Oktober 2021 um 13:08 Uhr
Ich weiß es nicht, aber wenn es verfügbar ist,
LZCNT
scheint ein wahrscheinlicher Kandidat zu sein. (Sehen de.wikipedia.org/wiki/SSE4)– Ruben
19. Februar 2012 um 22:40 Uhr