取模操作是否更快,功率为 2,即使在编译时该值未知

Is the modulo operation faster with a power of two even if the value is not known at compile time?

本文关键字:编译 未知 是否 操作 功率      更新时间:2023-10-16

在下面的代码中:

i = x % b;

b 是 2 的幂时,取模运算是否更快,即使在编译时不知道b(即即使编译器不会将其优化为按位,并且因为它不知道b将是 2 的幂)?如果不是,如果我知道b将始终是 2 的幂,我怎么能强制进行这样的优化?

编辑:我想我在问题的第一部分真正要问的是divl指令(或类似指令)本身是否会在 2 的幂下运行得更快。

它是否更快显然必然取决于系统。

如果您知道x是非负数,并且b是 2 的幂,则可以使用 x & (b - 1)

x86 处理器中当前实现中的dividiv确实具有取决于其操作数的执行时间,但间接执行。这实际上取决于结果的大小。除法使结果为 0 或 1 比除法并获得大结果更快(但肯定不快)。确切的细节取决于微架构,性能差异可以更大或更小。

但是在我所知道的任何实现中,它都不关心 2 的幂,并且在我所知道的所有实现中,即使在最好的情况下,它甚至比使用按位 AND 慢得多,至少是 9 倍(Core2 45nm),但通常更像 20,甚至比 64 位操作数更糟糕。

如果编译器知道b是 2 的幂,它可能会对此做一些事情,但这通常是为明显的情况保留的,例如编译时常量(不一定是文字)或创建为 1 << n 的值。在更多情况下,编译器可以弄清楚它,或者更少。无论如何,这里的重点是,如果你知道是不够的,编译器必须知道,而且规则显然是编译器特定的。

代码是否会在运行时执行优化(这就是你要问的)取决于编译器,但我怀疑很多人会这样做。 如果你知道b是 2^n,只需写:

i = x & ((1 << n) - 1);

您将始终获得优化。