Live data from Hacker News

Bit Twiddling Hacks

graphics.stanford.edu

11–20 of 38 posts

Re: Bit Twiddling Hacks

#11
This kind of hacks is a major part of how we made Scala.js' 64-bit integers fast (the fastest known implementation of 64-bit integers on JavaScript). See [1] for the implementation, and [2] at section 4.4 for the long explanation with benchmarks and the other tricks we use.

[1] https://github.com/scala-js/scala-js/blob/v1.3.1/linker-priv...

[2] https://lampwww.epfl.ch/~doeraene/thesis/doeraene-thesis-201...

Re: Bit Twiddling Hacks

#12
My favorite thing about these is how they come full circle - programmers find convoluted ways to outsmart the compiler in some primitive operation, but then CPU manufacturers add dedicated instructions for those operations, and eventually the compilers outsmart the programmer by deleting their smartass method and emitting a single instruction instead

https://godbolt.org/z/nPdrcz

Re: Bit Twiddling Hacks

#13
This list is super-great, except: all modern targets[0] (and many non-modern, including Alpha, Cray, CDC, Stretch) have the POPCOUNT instruction, which does a key operation underlying a large portion of the target operations much faster than presented. It provides an order-of-magnitude speedup in numerous algorithms. The list should have a comprehensive treatment.

At the moment, the only ISO Standard way to say "popcount" is in C++, with e.g.

  std::bitset(x).count()
But even this is insufficient on MSVC, which targets pre-2002 arm64, which lacked it; and on gcc and clang on amd64, similarly, absent a -fpopcnt or -march=native or related option (which there are numerous other reasons to use).

Given -march=native or =core2 or various other means, optimizers will happily rewrite the Kernighan loop into a straight-up POPCNT instruction. Anyway, all compilers provide it as a non-standard, therefore variously-spelled, intrinsic, but (except on MSVC) only actually produce it if the "-march=" or related commad-line option enables that.

Historically, it is common for instruction sets to start out lacking the instruction, and then getting it in subsequent releases because of customer demand. Also historically, a key such customer has frequently been the US NSA. Thus, initial and64, alpha, POWER, and SPARC lacked it, but soon got it. x86 ("ia32") is perhaps the principal laggard. When a feature is added, at great expense, to a subsequent ISA revision, that says a lot for its importance.

[0] All except RISC-V, to date. Some would say this makes RISC-V non-modern. It appears in the (still) unratified B extension, which (therefore) nobody implements.

Re: Bit Twiddling Hacks

#15
post #12

My favorite thing about these is how they come full circle - programmers find convoluted ways to outsmart the compiler in some primitive operation, but then CPU manufacturers add dedicated instructions for those operations, and eventually the compilers outsmart the programmer by deleting their smartass method and emitting a single instruction instead https://godbolt.org/z/nPdrcz

This of course refers to the POPCNT instruction, that is still quite tricky to get compilers to generate reliably, and which RISC-V specifications and all implementations to date mysteriously lack.

Compilers failing to generate POPCNT cause sometimes 10x slowdowns in key operations.

Re: Bit Twiddling Hacks

#16
post #7

I once had to count the number of set bits (the Hamming weight) for an assignment. It had to be done in under 40 bitwise ops, without loops and with constants of up to 8 bits. The naive approach took way too many ops! I was stumped until I found the linked page, in particular 'Counting bits set, in parallel'[1]. Parallelism at the bit level?! That is when I realized low level programming was completely badass. [1]: h…

Again, the POPCNT instruction reveals its importance.

Re: Bit Twiddling Hacks

#17
post #15
post #12

My favorite thing about these is how they come full circle - programmers find convoluted ways to outsmart the compiler in some primitive operation, but then CPU manufacturers add dedicated instructions for those operations, and eventually the compilers outsmart the programmer by deleting their smartass method and emitting a single instruction instead https://godbolt.org/z/nPdrcz

This of course refers to the POPCNT instruction, that is still quite tricky to get compilers to generate reliably, and which RISC-V specifications and all implementations to date mysteriously lack. Compilers failing to generate POPCNT cause sometimes 10x slowdowns in key operations.

Indeed it's better to use intrinsics in new code rather than rely on compiler magic

https://godbolt.org/z/n3z8nz

Portability is an issue though, that works on GCC/Clang but you need a different intrinsic for MSVC

Re: Bit Twiddling Hacks

#18
post #9

At my last job interview I had to implement popcount and explain how to optimise it (amongst other things). I was able to jot down a naïve implementation and the obvious optimisation based on a lookup tables. I only vaguely remembered the Bit Twiddling treatment of the subject but, with a bit of nudging from the interviewer, I managed to implement and explain the variant that runs in O(set bits) (“Brian Kernighan's w…

I’ve had that question twice in google phone screen interviews, and iirc, the best answer has changed from the hash table thing to just use the hardware instruction.

Re: Bit Twiddling Hacks

#19
post #9

At my last job interview I had to implement popcount and explain how to optimise it (amongst other things). I was able to jot down a naïve implementation and the obvious optimisation based on a lookup tables. I only vaguely remembered the Bit Twiddling treatment of the subject but, with a bit of nudging from the interviewer, I managed to implement and explain the variant that runs in O(set bits) (“Brian Kernighan's w…

I mean, it wouldn't hurt to know how to do all of this, plus all the data structures & algorithms stuff, plus all major and minor details about your language and environment of choice, plus anything else that someone deems important, but realistically most of us need a job before you can learn all of that. Even if you do learn it all, people tend to lose knowledge they don't use, so it may have an expiration date depending on how good your brain is. New technologies and advancements can also introduce more knowledge that becomes required to know for interviews. The pool of knowledge for interview questions might continue to grow until you'd have to study for a year or more to have a high chance of passing it.

Re: Bit Twiddling Hacks

#20
post #9

At my last job interview I had to implement popcount and explain how to optimise it (amongst other things). I was able to jot down a naïve implementation and the obvious optimisation based on a lookup tables. I only vaguely remembered the Bit Twiddling treatment of the subject but, with a bit of nudging from the interviewer, I managed to implement and explain the variant that runs in O(set bits) (“Brian Kernighan's w…

I’ve had that question twice in google phone screen interviews, and iirc, the best answer has changed from the hash table thing to just use the hardware instruction.

I don't believe companies want to hire for knowing that popcnt exists. The interviewer should follow up with the hypothetical situation when either the language or the CPU doesn't have the instruction.

Nobody should ask this anyway, this has become the fizzbuzz type of question.

Post reply on HN