C speed of comparison: Equals "==" vs Bitwise and "&"

1.3k Views Asked by At

Suppose I have an integer that is a power of 2, eg. 1024:

int a = 1 << 10; //works with any power of 2 no.

Now I want to check whether another integer b is the same as a. Which is faster/better (especially on weak embedded systems):

if (b == a) {}

or

if (b & a) {}

?

Sorry if this is a noob question, but couldn't find an answer using the search.

edit: thanks for many insightful answers. I could select only one of them, but all of them are welcome.

3

There are 3 best solutions below

0
Roguebantha On BEST ANSWER

The short answer is this - it depends on what sort of things you're comparing. However, in this case, I'll assume that you're comparing two variables to each other (as opposed to a variable and an immediate, etc.)

This website, although rather old, studied how many clock cycles different instructions took on the x86 platform. The two instructions we're interested in here are the "AND" instruction and the "CMP" instruction (which the compiler uses for & and == respectively). What we can see here is that both of these instructions take about 1/3 of a cycle - that is to say, you can execute 3 of them in 1 cycle on average. Compare this to the "DIV" instruction which (in 1996) took 23 cycles to execute.

However, this omits one important detail. An "AND" instruction is not sufficient to complete the behavior you're looking for. In fact, a brief compilation on x86_64 suggests that you need both an "AND" and a "TEST" instruction for the "&" version, while "==" simply uses the "CMP" instruction. Because all these instructions are otherwise equivalent in IPC, the "==" will in fact be slightly faster...as of 1996.

Nowadays, processors optimize so well at the bare metal layer that you're unlikely to notice a difference. That said, if you wanted to see for sure...simply write a test program and find out for yourself.

As noted above though, even in the case that you have a power of 2, these instructions are still not equivalent, since it doesn't work for 0. Well...I guess technically zero ISN'T a power of 2. :) However you want to spin it though, use "==".

0
cmaster - reinstate monica On

An X86 CPU sets a flag according to how the result of any operation compares to zero.

For the ==, your compiler will either use a dedicated compare instruction or a subtraction, setting this flag in both cases. The if() is then implemented by a jump that is conditional on this bit.

For the &, another instructions is used, the logical bitwise and instruction. That too sets the flag appropriately. So, again, the next instruction will be the conditional branch.

So, the question boils down to: Is there a performance difference between a subtraction and a bitwise and instruction? And the answer is "no" on any sane architecture. Both instructions use the same ALU, both set the same flags, and this ALU is typically designed to perform a subtraction in a single clock cycle.


Bottom line: Write readable code, and don't try to microoptimize what cannot be optimized.

6
Stephan Lechner On

These operations are not even equivalent, because a & b will be false when both a and b are 0. So I'd suggest to express the semantics that you want (i.e. a == b) and let the compiler to the optimization.

If you then measuer that you have performance issues at that point, then you can start analyzing/optimizing...