Counting '1' Bits in Binary Blocks - Fast C++ Code

Click For Summary

Discussion Overview

The discussion revolves around counting the number of '1' bits in binary blocks using C++ code. Participants explore various methods for achieving this efficiently, including existing fast algorithms and compiler optimizations.

Discussion Character

  • Technical explanation
  • Exploratory
  • Debate/contested

Main Points Raised

  • One participant presents a specific example of splitting a binary integer into blocks and expresses interest in modifying existing fast algorithms for counting '1' bits.
  • Another participant suggests a simple loop method for counting bits, emphasizing the use of a counter variable and bit manipulation.
  • A third participant advises using a profiler to identify bottlenecks in code before attempting optimizations, cautioning against "premature optimization."
  • Discussion includes the mention of hardware-accelerated instructions like POPCNT available on some Intel and AMD processors, which can count bits directly.
  • Another participant notes the availability of a built-in function in gcc for counting '1' bits, suggesting a fallback mechanism if the intrinsic is not supported.

Areas of Agreement / Disagreement

Participants present multiple approaches and tools for counting '1' bits, with no consensus on a single best method. The discussion remains open with various competing views on optimization strategies and techniques.

Contextual Notes

Some participants highlight the importance of profiling and compiler optimizations, indicating that the effectiveness of different methods may depend on specific hardware and compiler capabilities.

burritoloco
Messages
81
Reaction score
0
Hi,

For example, say we have the binary integer 101010 and I split it into blocks, say (1)(01)(01)(0). The size of the blocks is determined by some function. We want to count the number of '1' bits inside each of these blocks.

I'm interested in a fast C++ code to do this. There are fast codes out there to compute the number of '1' bits in arbitrary integers, and it would be great if the solution to this problem could be obtained by a modification of those codes (which I do not understand), so that it is as fast as it can be. For instance, here's one of those "ugly" fast codes (the one I'm using in my project) which I found in another forum:

int bitcount(int i) {
i = i - ( (i >> 1) & 0x55555555);
i = (i & 0x33333333) + ( (i >> 2) & 0x33333333 );
return (((i + (i >> 4)) & 0x0F0F0F0F) * 0X01010101) >> 24;
}


Many thanks for the help.
 
Technology news on Phys.org


Hey burritoloco and welcome to the forums.

You can do this with a very simple loop. You loop over all bits in a block and have a counter variable for the number of bits in a block (initialized to zero). Then in the loop you simply do counter += ((Block_Value) >> loop_index) & 1.

What the above does is move the bit of interest to the LSB and then you 'AND' it by 1 to get the value of that bit. Loop_index should start at 0 and go to Num_Block_Bits - 1 inclusive.
 


1) Get hold of a profiler like "gprof" (for gcc) or "valgrind". These time the execution of a program and can break down the time spent in each function, etc.

I consider trying to optimise code without a profiler is unwise. This is "premature optimisation". You think that function is a bottleneck, but how do you know without a profiler?

2) If you compile with optimisations turned on (example: -O2 in gcc) the compiler itself will optimise the code in certain ways. It may completey ignore some branches in your code, or change divisions to bitwise operations, etc,

This is another reason to avoid premature optimisation. The compiler is a "mystery black box" with relation to the source code, so you need a profiler to compare the differences.

3) The code you have given makes use of bit shifting, which is almost certainly hardware accelerated. I would have to check that, but I would be shocked if modern Intel CPUs did not have a hardware circuit specially for this. Again this is further justification for the neccessity of a profiler.
 


Nice catch.

On my compiler of choice (gcc) it is:

int __builtin_popcount (unsigned int x)
Returns the number of 1-bits in x.

What I would do is autoconf to check it exists and is supported on the hardware. If it does, #define it in. If it doesn't, use my own code.

The function is documented in gcc here: http://gcc.gnu.org/onlinedocs/gcc-4.5.3/gcc/Other-Builtins.html
 

Similar threads

  • · Replies 13 ·
Replies
13
Views
2K
  • · Replies 23 ·
Replies
23
Views
3K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 39 ·
2
Replies
39
Views
4K
  • · Replies 5 ·
Replies
5
Views
2K
Replies
7
Views
4K
  • · Replies 13 ·
Replies
13
Views
4K
  • · Replies 6 ·
Replies
6
Views
2K
  • · Replies 29 ·
Replies
29
Views
10K
  • · Replies 5 ·
Replies
5
Views
2K