Setting and removing a specific bit in a 64-bit integer

Ok, I want pretty straightforwardly:

  • Set the Nth bit of a number (= make it "1")
  • Discard the Nth bit of a number (= make it "0")

This is my code so far (in the form of 2 macros):

#define SETBIT(X,Y) X|=(1ULL<<(Y)) #define UNSETBIT(X,Y) X&=(~(1ULL<<(Y))) 

They both work fine. The fact is that:

  • Is there anything that could be optimized?
  • Can it do it even faster?

(Both operations must be performed several million times per second, so performance is more than important).

+4
source share
4 answers

You can slightly speed up compilation time by getting rid of macros, but more on that. A bit of hiding is fast enough, so this should not be a problem.

This is an idiomatic way to do this; I would not change anything.

+6
source

This is the standard way to set and clear bits in C.

If you want to speed up these macros, you can take a look at the Linux assembly implementation of these operations.

For example, for x86 :

http://lxr.linux.no/linux/arch/x86/include/asm/bitops.h

Find the __clear_bit and __set_bit built-in functions.

+3
source

These macros are optimal and idiomatic, so the compiler will probably recognize these expressions if there are optimizations.

The only acceleration you can get is ... to avoid using them if there are better alternatives. If you often perform the same operation with multiple bits (for example, turn on bits 0, 2, and 4), you can get something by doing all these operations, for example. one or instead of using multiple SETBIT s.

+2
source

First of all, you should fix the macros this way:

 #define SETBIT(X,Y) ( (X) |= 1ULL << (Y) ) #define UNSETBIT(X,Y) ( (X) &= ~(1ULL << (Y)) ) ) 

Thus, a code of type SETBIT(a, 2) + 1; will work as expected, and SETBIT(1+a, 2); will result in an error as expected.

You will probably never use macros this way, but the extra parentheses are free anyway, and the solution to macros might be a PITA that always adds extra macros () or {} .

ADDITION: With a built-in assembly and a processor with a bit rotation operation and provided that Y not known at compile time, UNSETBIT can be done faster, avoiding NOT ... Pseudo-code:

 X = X OR (0xFFFFFFFFFFFFFFFE ROL Y) 

Then, when these macros are just as efficient as they are (the C compiler should optimize them to perfect assembly instructions), you should probably provide macros to control multiple bits, for example:

 #define SET2BITS(X, B1, B2) ( (X) |= 1ULL << (B1) | 1ULL << (B2) ) 

Also, in some situations, a function macro for using internal expressions may be more efficient (although optimizing the compiler is likely to achieve the same end result):

 #define BITSETVAL(X, B) ( (X) | 1ULL << (B) ) 
+2
source

All Articles