优化与零的简单比较以提高性能
Optimize simple comparison with zero for performance
我的代码中有一个瓶颈(大约 20% CPU 时间)在以下 if 语句中:
if (a == 0) { // here
...
}
其中 a
是一个 uint8_t
,因此是一个从 0 到 255 的数字。
是否有任何低级优化使其更快?
我考虑过使用按位 NOR (~(a| 0))
,但只有当 a
是 1 位时才有效,对吗?
以防万一:在这种特殊情况下,我不关心代码的可读性。
除非你的编译器是垃圾,否则你无法做任何事情来加速整数比较。
但是,您观察到的瓶颈可能并不是真正的比较本身,而是不幸的分支预测的结果。
有两种方法可以解决这个问题:
如果 "to branch or not to branch" 遵循某种模式,请将最后一秒的决定进一步移至您可以使用该模式的程序逻辑中,只是不要在您的程序中分支热点功能。这可能需要认真思考。一种确定是否有模式的 hacky 方法:如果分支则打印 1
,如果调用足够多则打印 0
,Zip 启动并查看生成的存档是否比数字小得多(以位为单位)你打印的值。 (当然,如果你更喜欢理论,也有一些聪明的公式。)
如果大多数时候你选择一个分支而不是另一个分支,你可以告诉编译器哪个分支是可能的分支。使用 gcc,检查 __builtin_expect
,对于其他编译器,请阅读手册。
对于两种解决方案都很重要:您需要衡量这是否真的有帮助。尤其是第二个不会神奇地变得更好,它甚至可能让事情变得更糟。
我的代码中有一个瓶颈(大约 20% CPU 时间)在以下 if 语句中:
if (a == 0) { // here
...
}
其中 a
是一个 uint8_t
,因此是一个从 0 到 255 的数字。
是否有任何低级优化使其更快?
我考虑过使用按位 NOR (~(a| 0))
,但只有当 a
是 1 位时才有效,对吗?
以防万一:在这种特殊情况下,我不关心代码的可读性。
除非你的编译器是垃圾,否则你无法做任何事情来加速整数比较。
但是,您观察到的瓶颈可能并不是真正的比较本身,而是不幸的分支预测的结果。
有两种方法可以解决这个问题:
如果 "to branch or not to branch" 遵循某种模式,请将最后一秒的决定进一步移至您可以使用该模式的程序逻辑中,只是不要在您的程序中分支热点功能。这可能需要认真思考。一种确定是否有模式的 hacky 方法:如果分支则打印 1
,如果调用足够多则打印 0
,Zip 启动并查看生成的存档是否比数字小得多(以位为单位)你打印的值。 (当然,如果你更喜欢理论,也有一些聪明的公式。)
如果大多数时候你选择一个分支而不是另一个分支,你可以告诉编译器哪个分支是可能的分支。使用 gcc,检查 __builtin_expect
,对于其他编译器,请阅读手册。
对于两种解决方案都很重要:您需要衡量这是否真的有帮助。尤其是第二个不会神奇地变得更好,它甚至可能让事情变得更糟。