替代在C++中使用%运算符和/运算符

kik*_*iki 11 c++ modulo processing-efficiency

有人告诉我,模运算符"%"和除运算符"/"在嵌入式C++中效率很低.

我怎样才能实现以下表达式:

a = b % c;
Run Code Online (Sandbox Code Playgroud)

我知道这可以使用以下逻辑来实现:

a = b - c;
while (a >= c) {
  a = a - c;
}
Run Code Online (Sandbox Code Playgroud)

但我的问题是,与%运算符相比,这个代码涉及while循环是否足够有效?

谢谢,Kirti

Bas*_*tch 18

无论你做什么,分区和模数都是昂贵的硬件操作(这与硬件架构比与语言或编译器更相关),可能比添加慢十倍.

但是,在当前的笔记本电脑或服务器以及高端微控制器上,缓存未命中通常比分部慢得多!

当除数是常数时,GCC编译器通常能够优化它们.

您的朴素循环通常比使用硬件除法指令(或库程序执行它,如果不是由硬件提供)慢得多.我相信你在避免分裂并用循环替换它是错误的.

您可以调整算法 - 例如,使用两次幂 - 但我不建议您使用您的代码.请记住,过早优化是邪恶的,所以首先尝试让您的程序正确,然后对其进行分析以找到问题点.


Dan*_*Dan 7

没有什么比%运营商更有效率了.如果有更好的方法,那么任何合理的编译器都会自动转换它.当你被告知%并且/效率低下时,那只是因为那些操作很困难 - 如果你需要执行模数,那就去做吧.

有更好的方法可能有特殊情况 - 例如,mod的2的幂可以写成二进制或 - 但这些可能由编译器优化.


she*_*les 5

该代码几乎肯定会慢于您的处理器/编译器决定执行divide/mod.通常,基本算术运算符很难获得快捷方式,因为mcu/cpu设计者和编译器程序员非常擅长为几乎所有应用程序优化它.

嵌入式设备中的一个常见捷径(每个周期/字节可以产生差异)是将所有内容保留在base-2中以使用位移运算符执行乘法和除法,并按位和(&)执行模数.

例子:

unsigned int x = 100;
unsigned int y1 = x << 4;   // same as x * 2^4 = x*16
unsigned int y2 = x >> 6;   // same as x / 2^6 = x/64
unsigned int y3 = x & 0x07; // same as x % 8
Run Code Online (Sandbox Code Playgroud)

  • 当右操作数是2的幂幂常数时,任何体面的编译器都会为您进行相同的优化.从编译器优化开始的早期开始,比特移位/屏蔽技巧是一个遗留问题,并且不再需要. (3认同)