0

我有一个简短的问题,关于如何加快无限级数的计算。这只是示例之一: 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++ 的应用程序,但我正在寻找抽象解决方案,所以没关系。谢谢您的回复。

4

3 回答 3

7

您需要分解问题以匹配您拥有的处理器或线程的数量。在您的情况下,您可以让一个处理器处理偶数项,另一个处理奇数项。您无需预先计算 x^2 并使用 lastX*(x^2),而是使用 lastX*(x^4) 跳过每隔一个术语。要使用 8 个处理器,请将前一项乘以 x^16 以跳过 8 个项。

PS 大多数时候,当遇到这样的问题时,寻找一种更有效的计算结果的方法是值得的。大多数时候,更好的算法会击败更多的马力。

于 2010-10-07T22:25:05.633 回答
2

如果您要计算数百万个位置的 pi 值或其他值,您首先要密切注意选择一个快速收敛且适合并行化的系列。然后,如果你有足够的数字,将它们拆分到多个处理器中最终会变得更划算;您将必须找到或编写一个可以做到这一点的 bignum 库。

请注意,您可以通过各种方式分解变量;例如:

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...]

然而,这种加速并不像你想象的那么简单,因为每次计算所花费的时间取决于保持它所需的精度。在设计算法时,您需要考虑到这一点;此外,您的代数也密切相关;即,对于上述情况,如果您按常数进行常规除法,您将获得无限重复的分数,因此您需要想办法以一种或另一种方式处理它。

于 2010-10-07T23:14:15.083 回答
1

好吧,对于这个例子,你可以总结这个系列(如果我在正确的地方有括号):

(-1)^i * (x^(2i + 1))/(2i + 1)

然后在处理器 1 of 8 上计算 i = 1, 9, 17, 25, ... 项的总和

然后在处理器 2 of 8 上计算 i = 2, 11, 18, 26, ...

依此类推,最后将部分总和相加。

或者,您可以按照您(几乎)建议的方式,将 i = 1..16(比如说)给处理器 1,给处理器 2 i = 17..32,依此类推,他们可以从前一个。如果您想要系列中超过 8x16 个元素,则首先为每个处理器分配更多元素。

对于这个例子,我怀疑是否值得并行化,我怀疑你会在并行线程仍在唤醒时在 1 个处理器上获得双精度精度;但这只是这个例子的一个猜测,你可能有很多并行化值得努力的系列。

而且,正如@Mark Ransom 已经说过的那样,更好的算法应该每次都能击败蛮力和大量处理器。

于 2010-10-07T22:39:42.760 回答