C 比较速度:等于“==” vs Bitwise 和“&”

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

假设我有一个整数,它是 2 的幂,例如。 1024:

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

现在我想检查另一个整数 b 是否与 a 相同。这是 faster/better(尤其是在弱嵌入式系统上):

if (b == a) {}

if (b & a) {}

?

抱歉,如果这是一个菜鸟问题,但无法通过搜索找到答案。

编辑:感谢许多有见地的回答。我只能 select 其中之一,但欢迎大家。

X86 CPU 根据任何操作的结果与零的比较设置标志。

对于 ==,您的编译器将使用专用的比较指令或减法,在这两种情况下都设置此标志。 if() 然后通过以该位为条件的跳转实现。

对于&,使用了另外一条指令,逻辑位与指令。这也适当地设置了标志。所以,同样,下一条指令将是条件分支。

因此,问题归结为:减法与按位与指令之间是否存在性能差异?答案是 "no" 在任何理智的体系结构上.两条指令使用相同的 ALU,都设置相同的标志,并且该 ALU 通常设计为在单个时钟周期内执行减法。


底线:编写可读代码,不要尝试对无法优化的内容进行微优化。

这些操作甚至不等价,因为当 ab 都是 0 时,a & b 将是 false。 所以我建议表达你想要的语义(即a == b)并让编译器进行优化。

如果您随后测量您在那个时候遇到了性能问题,那么您可以开始analyzing/optimizing...

简短的回答是这样的——这取决于你比较的是什么类型的东西。但是,在这种情况下,我假设您正在相互比较两个变量(而不是变量和立即数等)

This website,虽然比较老,研究了不同指令在x86平台上占用了多少个时钟周期。我们在这里感兴趣的两条指令是 "AND" 指令和 "CMP" 指令(编译器分别将其用于 & 和 ==)。我们在这里可以看到,这两条指令都需要大约 1/3 的周期——也就是说,你平均可以在 1 个周期内执行其中的 3 条。将此与(1996 年)执行 23 个周期的 "DIV" 指令进行比较。

然而,这忽略了一个重要的细节。 "AND" 指令不足以完成您正在寻找的行为。事实上,对 x86_64 的简短编译表明您需要针对“&”版本的 "AND" 和 "TEST" 指令,而“==”仅使用 "CMP" 操作说明。因为所有这些指令在 IPC 中都是等效的,所以“==”实际上会稍微快一些......截至 1996 年。

如今,处理器在裸机层的优化非常好,您不太可能注意到差异。也就是说,如果您想确定...只需编写一个测试程序并自己找出答案。

如上所述,即使你有 2 的幂,这些指令仍然不等价,因为它不适用于 0。好吧......我想从技术上讲,零不是2 的幂。:) 但是你想旋转它,使用“==”。