取模操作是否更快,功率为 2,即使在编译时该值未知
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 的幂下运行得更快。
它是否更快显然必然取决于系统。
如果您知道x
是非负数,并且b
是 2 的幂,则可以使用 x & (b - 1)
。
x86 处理器中当前实现中的div
和idiv
确实具有取决于其操作数的执行时间,但间接执行。这实际上取决于结果的大小。除法使结果为 0 或 1 比除法并获得大结果更快(但肯定不快)。确切的细节取决于微架构,性能差异可以更大或更小。
但是在我所知道的任何实现中,它都不关心 2 的幂,并且在我所知道的所有实现中,即使在最好的情况下,它甚至比使用按位 AND 慢得多,至少是 9 倍(Core2 45nm),但通常更像 20,甚至比 64 位操作数更糟糕。
如果编译器知道b
是 2 的幂,它可能会对此做一些事情,但这通常是为明显的情况保留的,例如编译时常量(不一定是文字)或创建为 1 << n
的值。在更多情况下,编译器可以弄清楚它,或者更少。无论如何,这里的重点是,如果你知道是不够的,编译器必须知道,而且规则显然是编译器特定的。
代码是否会在运行时执行优化(这就是你要问的)取决于编译器,但我怀疑很多人会这样做。 如果你知道b
是 2^n,只需写:
i = x & ((1 << n) - 1);
您将始终获得优化。
相关文章:
- 使用 make 编译 MPI,几个命名空间错误,例如"错误:未知类型名称'使用'?
- 编译 Boost 时在 OS X 上的"ld:未知选项:-soname"
- 如何定义在编译时数据未知的 const 数组
- Cuda C++设计:编译时大小未知的可重用类
- GCC 编译时出现警告:未知转义序列:"\040"
- 使用来自C++的任意数量的参数(在编译时未知)调用 Python 函数
- 如何创建指向派生类的新指针,该派生类在C++编译时未知
- 未知 使用用于C++代码的标头编译 C 代码时char16_t未知类型名称
- 当Mac Mojave中的C 编译时,C编译器识别是未知的
- STXXL的任何STXXL替代方案都可以在编译时处理未知大小或任何技巧
- 如何在将我的 QT 应用程序交叉编译为 raspberry-pi3 时修复未知错误
- 无法编译任何C++程序;错误:未知类型名称'uint8_t'
- 为 freebsd 11 编译 gcc4.8.5 时出错: 错误: 未知类型名称 'choke'
- 在编译时初始化一个C++结构,就像一个未知绑定的数组
- 在编译时推导具有未知类型的函数重载
- 如何修复未知编译指示 gcc 警告
- 当编译时参数未知时,不调用"constexpr"构造函数
- 是否可以声明指向未知(编译时)返回类型的函数的指针
- 在 OSX 10.9.1 上使用 g++ 编译时出错:未知类型名称'__darwin_wctype_t'
- 如果两个维度在编译时都是未知的,如何传递二维数组