Re:The NSA Instruction (2019)
by jart on Saturday June 12, 2021 @08:50AM
(#27484106)
Try the Cosmopolitan Libc implementation of popcnt(). It uses CPUID checks for compatibility which get hoisted out of a tight loop by the optimizer so there's no performance loss when building for -march=k8. If you build for -march=native then they get DCE'd entirely. See https://github.com/jart/cosmopolitan/blob/master/libc/bits/p...
[ Parent
| on HN ]
Because of a bug in a bunch of Intel chips, something like the following is probably better.
asm(
"mov\t%1,%0\n"
"popcnt\t%1,%1"
: "=r"(Res) : "r"(Pop) : "cc");
(assuming intel syntax)Thanks you just helped tons of my code go faster. Turns out false output dependency is a much bigger issue for bsr and bsf with 32-bit operands since it impacts all models and GCC builtins like __builtin_clz(x)^31 won't xor the output unless you use -march=native. So once again I find myself replacing compiler apis with stallman notation. For what it's worth:
asm("popcnt\t%0,%0" : "=r"(res) : "0"(pop) : "cc");
Can generate the mov statement automatically.