I'm quite fond of this classic for popcount [1]: int popcnt(unsigned int n) { int p = 0; while (n) { p++; n &= n-1; } return p; } But it has a branch in it, so I don't know if it's competitive with the "simple" version of just counting the ones or this version, even though the loop should run fewer iterations. Obviously the real answer is to just use the compiler intrinsics for this, but what fun is that? [1]: https:…
Counting set bits in an interesting way
11–20 of 34 posts
Re: Counting set bits in an interesting way
#12I'm quite fond of this classic for popcount [1]: int popcnt(unsigned int n) { int p = 0; while (n) { p++; n &= n-1; } return p; } But it has a branch in it, so I don't know if it's competitive with the "simple" version of just counting the ones or this version, even though the loop should run fewer iterations. Obviously the real answer is to just use the compiler intrinsics for this, but what fun is that? [1]: https:…
If the compiler is allowed to do loop idiom recognition and scalar optimization, writing the dumb thing rather than reaching for an intrinsic can have the same result as the intrinsic.
Re: Counting set bits in an interesting way
#13Earlier quoted context omitted.
If the compiler is allowed to do loop idiom recognition and scalar optimization, writing the dumb thing rather than reaching for an intrinsic can have the same result as the intrinsic.
That's true, but in any scenario where it mattered, I'd hate to rely on it. Compilers have the idiom recognition pass as a sort of hack for speeding up existing codebases but it's ultimately just a heuristic. When I write code, I would much prefer to be explicit about things like that.
Re: Counting set bits in an interesting way
#14Many languages have standard library functions, or hardware intrinsics, to emit these instructions: std::popcount in C++/20, _popcnt32 and _popcnt64 intrinsics for Intel/AMD, __builtin_popcount in gcc/clang, BitOperations.PopCount in C#, etc.
Re: Counting set bits in an interesting way
#15There is a chapter by Hank Warren all about popcount in the Beautiful Code book, https://www.oreilly.com/library/view/beautiful-code/97805965... and there is much more along similar lines in Warren’s book Hacker’s Delight https://en.m.wikipedia.org/wiki/Hacker's_Delight My favourite use of popcount is for packing sparse vectors.
Interesting, can you describe a sparse vector and how it’s packed using pop count?
"You can use popcount() to implement a sparse array of length N containing M FWIW: These kind of sparse array tricks have been around forever:
https://gcc.gnu.org/ml/gcc-patches/2007-03/msg01308.html
The original idea for that patch didn't come from philip bagwell's paper, but from some code from the late 80's i saw at IBM.
Thus, i suspect this kind of thing has been around forever
Re: Counting set bits in an interesting way
#16Earlier quoted context omitted.
That's true, but in any scenario where it mattered, I'd hate to rely on it. Compilers have the idiom recognition pass as a sort of hack for speeding up existing codebases but it's ultimately just a heuristic. When I write code, I would much prefer to be explicit about things like that.
You should be explicit, but equally profile before worrying about this stuff.
Re: Counting set bits in an interesting way
#17I never realized how much I hate this style of code until I started using Go. Go only allows Boolean conditions, so you have to do this:
> while (x >= 1)
Yeah, it's more code, but it's more readable too.
Re: Counting set bits in an interesting way
#18> while (x) I never realized how much I hate this style of code until I started using Go. Go only allows Boolean conditions, so you have to do this: > while (x >= 1) Yeah, it's more code, but it's more readable too.
while (x >>= 1)
This makes gcc compile the code to one instruction less per iteration because it can use the status flags generated by the bitshift to determine whether to jump. Now the loop will only be 3 instructions long and the entire function 8 instructions. https://godbolt.org/z/fna8de367
Re: Counting set bits in an interesting way
#19I'm quite fond of this classic for popcount [1]: int popcnt(unsigned int n) { int p = 0; while (n) { p++; n &= n-1; } return p; } But it has a branch in it, so I don't know if it's competitive with the "simple" version of just counting the ones or this version, even though the loop should run fewer iterations. Obviously the real answer is to just use the compiler intrinsics for this, but what fun is that? [1]: https:…
For those wondering how this works, n & n-1 zeros out the least significant 1. Simply by doing this repeatedly you count the number of 1s.
n = 464d 111010000b
n-1 = 463d 111001111b
n&(n-1) = 448d 111000000bRe: Counting set bits in an interesting way
#20I had this as an interview question years ago. I just used a table lookup. It's not compact, but it is fast.