用线程获得素数。如何划分间隔?

时间:2015-10-17 23:53:36

标签: java multithreading algorithm primes divide

我想获得区间[min, max]中的所有素数。我想在n服务器中进行微积分。哪个是在另一个n间隔中划分初始间隔的最佳方法,以便在所有n服务器中管理大致相同的负载?

[可选]

我有一个想法,但它没有像我预期的那样工作。我假设所有数字都是素数,因此需要验证的ii指令需要验证是否为素数。

如果我们记住这个方法:

然后,在区间[1,100]中获得素数的指令数为1+2+..+99+100 = 100(1+100)/2 = 5050

现在,如果我想在2个服务器(n=2)中进行此演算,我必须将此负载分配给每个(每个2525个指令)。我想要的间隔由2525 = x(1+x)/2 -> x=71定义。

一般而言,通用公式为Load = (Interval(x) - Interval(x-1) + 1) * (Interval(x-1) + Interval(x)) / 2,为Load = (max - min + 1) * (min + max) / (2 * n)

使用x and y = [1:9999999]n = 16执行此操作后,我得到了以下结果:

http://s2.subirimagenes.com/imagen/previo/thump_948211012c6a4f9423d5b03819d.png

我没有在所有服务器上获得相同的时间和指令,这意味着这不是划分间隔的方法。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

我认为你在寻找一种平行的方法。 这就是work stealing算法的设计目标,即Fork Join Pool。实际上,素数计算是工作窃取的一个典型用例,因为告诉n是否为素数需要迭代到sqrt(n),所以越大则需要更长的时间。因此,在工人之间平均分配它们并等待每个工人完成工作是不公平的,第一个核心将很快确定n是否为素数并且闲置,而另一个核心将忙于计算更大的数字。随着工作的窃取,空闲处理器将窃取其邻居队列的工作。

This implementation might be useful.

答案 1 :(得分:0)

我解决了这个问题。我没有对我的间隔进行第一次完整的划分,并将每个部分分配给不同的服务器。我决定将间隔分成很小的部分(例如[min, max]/length^2),每个微积分服务器都得到其中一个部分。当他们完成时,他们会得到另一个,直到没有更小的间隔来计算。

为什么我这样做?这是因为我无法确保我正在使用的服务器具有相同的微积分速度。