即使在编译时不知道值,模运算是否更快?
Is the modulo operation faster with a power of two even if the value is not known at compile time?
在下面的代码中:
i = x % b;
当 b
是 2 的幂时,模运算是否更快,即使 b
在编译时未知(即即使编译器不会将其优化为按位并且因为它不知道 b
将是 2) 的幂?如果不是,如果我知道 b
永远是 2 的幂,我怎么能强制进行这样的优化?
编辑:我想我在问题的第一部分真正要问的是 divl
指令(或类似指令)本身是否会 运行 更快地获得 2 的幂。
代码是否会在运行时执行优化(这就是您所要求的)取决于编译器,但我怀疑很多人会这样做。如果你知道 b
是 2^n,就写:
i = x & ((1 << n) - 1);
您将始终获得优化。
它是否更快显然必然取决于系统。
如果你知道 x
是非负数,b
是二的幂,你可以使用 x & (b - 1)
.
div
和 idiv
在 x86 处理器中的当前实现中确实有一个执行时间取决于它们的操作数,但间接地。这实际上取决于结果的大小。除法使结果为 0 或 1 比除法并获得大结果更快(但肯定不快)。具体细节取决于微架构,性能差异可能更大或更小。
但它不关心我所知道的任何实现中的 2 的幂,并且在我所知道的所有实现中,它甚至在最好的情况下比使用按位 AND 慢得多,至少慢了9(Core2 45nm)但通常更接近 20,甚至比 64 位操作数更差。
如果编译器知道 b
是 2 的幂,它可能会做一些事情,但这通常是为明显的情况保留的,例如编译时间常量(不一定是文字)或创建为1 << n
。您的编译器可以解决的情况可能更多,也可能更少。无论如何,这里的重点是,如果 你 知道是不够的,编译器必须知道,而且规则显然是特定于编译器的。
在下面的代码中:
i = x % b;
当 b
是 2 的幂时,模运算是否更快,即使 b
在编译时未知(即即使编译器不会将其优化为按位并且因为它不知道 b
将是 2) 的幂?如果不是,如果我知道 b
永远是 2 的幂,我怎么能强制进行这样的优化?
编辑:我想我在问题的第一部分真正要问的是 divl
指令(或类似指令)本身是否会 运行 更快地获得 2 的幂。
代码是否会在运行时执行优化(这就是您所要求的)取决于编译器,但我怀疑很多人会这样做。如果你知道 b
是 2^n,就写:
i = x & ((1 << n) - 1);
您将始终获得优化。
它是否更快显然必然取决于系统。
如果你知道 x
是非负数,b
是二的幂,你可以使用 x & (b - 1)
.
div
和 idiv
在 x86 处理器中的当前实现中确实有一个执行时间取决于它们的操作数,但间接地。这实际上取决于结果的大小。除法使结果为 0 或 1 比除法并获得大结果更快(但肯定不快)。具体细节取决于微架构,性能差异可能更大或更小。
但它不关心我所知道的任何实现中的 2 的幂,并且在我所知道的所有实现中,它甚至在最好的情况下比使用按位 AND 慢得多,至少慢了9(Core2 45nm)但通常更接近 20,甚至比 64 位操作数更差。
如果编译器知道 b
是 2 的幂,它可能会做一些事情,但这通常是为明显的情况保留的,例如编译时间常量(不一定是文字)或创建为1 << n
。您的编译器可以解决的情况可能更多,也可能更少。无论如何,这里的重点是,如果 你 知道是不够的,编译器必须知道,而且规则显然是特定于编译器的。