你能用整数运算代替浮点除法吗?

时间:2014-08-27 09:23:21

标签: c performance gcc embedded cortex-m

我使用的Cortex MCU不支持硬件中的浮点分割。 GCC编译器通过基于软件来解决这个问题,但警告说它可能非常慢。

现在我想知道如何完全避免它们。例如,我可以炸掉值因子10000(整数乘法),然后除以另一个大因子(整数除法),得到完全相同的结果。

但是这两个操作实际上是否比单个浮点操作更快?例如,替换:

是否有意义
int result = 100 * 0.95f

通过

int result = (100 * 9500) / 10000

得到95%?

2 个答案:

答案 0 :(得分:2)

如果可以的话,最好完全摆脱分裂。如果除数是编译时常量,则相对容易。通常,您会对事物进行排列,以便可以通过按位移位替换任何除法运算。所以对你的例子来说:

 unsigned int x = 100;
 unsigned int y = (x * (unsigned int)(0.95 * 1024)) >> 10; // y = x * 0.95

显然,您需要非常了解x的范围,以便避免中间结果溢出。

与往常一样,请记住,过早优化是邪恶的 - 只有在您发现性能瓶颈的情况下才使用此类定点优化。

答案 1 :(得分:1)

是整数表达式会更快 - 整数除法和乘法指令是单机器指令,而浮点运算将是函数调用(对于直接软件浮点)或异常处理程序(对于FPU指令仿真) - 无论哪种方式,每个操作将包含多个指令。

然而,对于简单操作,整数表达式和ad-hoc定点(缩放整数)表达式可能就足够了,因为涉及三角函数和对数等的数学密集型应用程序可能变得复杂。为此,您可以使用公共定点表示和库。这在C ++而不是C中最简单,例如Anthony Williams' fixed point library,由于广泛的运算符和函数重载,在大多数情况下,您可以简单地用{floatdouble关键字替换fixed或{{1}}个关键字对于许多操作而言,现有的表达式和算法可以与FPU装备的ARM相媲美。如果您不习惯使用C ++,则其余代码不需要使用任何特定于C ++的功能,并且基本上可以将C代码编译为C ++。