重新排列等式

我的C代码中有以下等式

k * dl * (1.0 + pHold / centre + (pHold * pHold) / (2.0 * centre * centre) - square / (2.0 * centre)) 

我知道浮点除法比乘法要贵得多,而且我已经和它搏斗了一段时间。 有没有办法重新排列这个来划分一个师?

谢谢

如果你看看分数的分母,你可以看到,制作一个共同面额将允许你只进行一次除法(以更多的乘法为代价):

 k * dl * (1.0 + pHold / (centre) - square / (2.0 * centre) + (pHold * pHold) / (2.0 * centre * centre) ) 

如果您确定浮点乘法优于浮点除法,那么:

 k * dl * (1.0 + (pHold * 2.0 * centre) / (2.0 * centre * centre) - (square * centre) / (2.0 * centre * centre) + (pHold * pHold) / (2.0 * centre * centre) ) 

哪个成了:

 k * dl * (1.0 + ( (pHold * 2.0 * centre) - (square * centre) + (pHold * pHold) ) / (2.0 * centre * centre) ) 

请注意,在您实际尝试优化某些部分之前,您应该:

  • 确保它是正确的
  • 确保如何在更高级别优化此function
    我的程序调用此计算的次数是否超过实际需要的次数?
    我可以使用以前的结果吗?什么是动态编程?
  • 一旦你知道瓶颈在哪里,就应该遵循以下标准:
    似乎很慢……它的“慢”程度如何? ……它应该如何“快速”?

但是如果你确定方程本身应该被优化,你可以使用centre的乘法逆在你的等式中出现4次这一事实,将除法计数减少到1:

 double centreInv = 1.0 / centre; double pHoldToCentre = pHold * centreInv; double result = k * dl * (1.0 + pHoldToCentre + 0.5 * pHoldToCentre * pHoldToCentre - 0.5 * square * centreInv); 

另请注意,这些更改实际上可能会影响此等式的结果,因此如果您决定更改它,请确保它仍然产生所需的输出。

在代数上,您可以将其减少为单个分区。 使用:

  • k代表k
  • d代表dl
  • ppHold
  • ccentre
  • ssquare

你的等式是:

  p pp s kd ( 1 + --- + ----- - --- ) c 2.cc 2.c 

转换为:

 kd ( 2.cc + 2.cp + pp - cs ) --------------------------------- 2.cc 

因此

 kd (2.c (c + p) - cs + pp) ----------------------------- 2.cc 

或者,就原始变量而言:

 (k * dl * (2 * centre * (centre + pHold) - centre * square + pHold * pHold)) / (2 * centre * centre) 

这是否与原始方程在数值上是一个单独的讨论。 为了讨论这个问题,我们需要知道方程中每个项的典型范围(即使这样,我的大脑也会受到伤害)。

你切出至少一个:

 k * dl * (1.0 + (pHold + (pHold * pHold) / (2.0 * centre) - square * 0.5) / centre) 

在过去,你可能会写

 oocenter = 1/center; 

并在表达式中使用它

 k * dl * (1.0 + pHold * oocentre + pHold * pHold * 0.5 * oocentre * oocentre - square * 0.5 * oocentre) 

如今,我相信编译器足够聪明,可以为你做到这一点。 我建议努力实现矢量化和并行化。

您可以将此减少到只有一个部门:

 k * dl * (2 * centre * (centre + pHold) + pHold * pHold - centre * square) / (2.0 * centre * centre) 

嗨,我不知道编程C 🙂

但是给定k,dl,pHold,center和square都是变量,你可以简化这个数学方程式:

  k*dl*(2.0* centre * centre + 2.0 * centre * pHold - centre *square + pHold * pHold) / (2.0 * centre * centre) 

将变量替换为单个字符变量并使用http://www.wolframalpha.com

编辑:Nikos C基本上有相同的答案,但是考虑到2c。 您可以测试/选择哪一个表现更好。