重新排列等式
我的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
-
p
为pHold
-
c
为centre
-
s
为square
你的等式是:
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。 您可以测试/选择哪一个表现更好。