我只是有一个简单的问题,关于如何加速无限系列的计算。 这只是其中一个例子: arctan(x)= x - x ^ 3/3 + x ^ 5/5 - x ^ 7/7 + ....
假设您有一些库可以让您使用大数字,那么首先明显的解决方案是开始添加/减去序列的每个元素,直到达到某个目标N.
你也可以预先保存X ^ n所以对于每个下一个元素而不是计算x ^(n + 2)你可以做lastX *(x ^ 2)
但总的来说,这似乎是非常顺序的任务,你可以做些什么来利用多个处理器(8 +)??。
非常感谢!
编辑: 我将需要计算从100k到1m迭代的东西。这是基于c ++的应用程序,但我正在寻找抽象的解决方案,所以它应该无关紧要。 谢谢你的回复。
答案 0 :(得分:7)
您需要将问题解决以匹配您拥有的处理器或线程数。在您的情况下,您可以使用例如一个处理偶数项的处理器和另一个处理奇数项的处理器。不使用lastX *(x ^ 2)预先计算x ^ 2,而是使用lastX *(x ^ 4)来跳过其他每个术语。要使用8个处理器,请将前一个项乘以x ^ 16,以跳过8个项。
P.S。大多数情况下,当遇到这样的问题时,寻找一种更有效的计算结果的方法是值得的。更好的算法在大多数时候都会超过更大的马力。
答案 1 :(得分:2)
如果你试图计算数百万个地方或某物的价值,你首先要密切注意选择一个快速收敛的系列,并且这个系列可以进行并行化。然后,如果你有足够的数字,最终将它们分成多个处理器将具有成本效益;你必须找到或写一个可以做到这一点的bignum图书馆。
请注意,您可以通过各种方式分解变量; e.g:
atan(x)= x - x^3/3 + x^5/5 - x^7/7 + x^9/9 ...
= x*(1 - x^2*(1/3 - x^2*(1/5 - x^2*(1/7 - x^2*(1/9 ...
虽然第二行比第一行的朴素实现更有效,但后一种计算从头到尾依然具有线性的依赖链。您可以通过成对组合术语来改善您的平行:
= x*(1-x^2/3) + x^3*(1/5-x^2/7) + x^5*(1/9 ...
= x*( (1-x^2/3) + x^2*((1/5-x^2/7) + x^2*(1/9 ...
= [yet more recursive computation...]
然而,这种加速并不像你想象的那么简单,因为每次计算所花费的时间取决于保持它所需的精度。在设计算法时,您需要考虑到这一点;而且,你的代数密切参与;也就是说,对于上述情况,如果你用常数进行常规除法,你将得到无限重复的分数,所以你需要找到某种方式来处理它,不管怎样。
答案 2 :(得分:1)
嗯,对于这个例子,你可以对系列求和(如果我在正确的位置有括号):
(-1)^i * (x^(2i + 1))/(2i + 1)
然后在8的处理器1上计算i = 1,9,17,25,...的项的总和
然后在8的处理器2上计算i = 2,11,18,26 ......的术语总和。
依此类推,最后加上部分金额。
或者,你可以像你(几乎)建议的那样,给i = 1..16(比如说)给处理器1,i = 17..32给处理器2,依此类推,他们可以计算每个连续的功率x来自前一个。如果您希望系列中有超过8x16个元素,那么首先要为每个处理器分配更多元素。
我怀疑,对于这个例子,它是否值得并行化,我怀疑你会在1个处理器上获得双精度精度,而并行线程仍在唤醒;但这只是对这个例子的一种猜测,你可能可以使用许多并行化值得努力的系列。
而且,正如@Mark Ransom已经说过的,一个更好的算法应该每次都击败蛮力和很多处理器。