用线程获取素数。如何划分区间?

Obtain primes with threads. How to divide intervals?

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


[可选]


我有一个想法,但它并没有像我预期的那样奏效。我假设所有数字都是素数,所以一个数字 i 需要 i 条指令来验证它是素数。

如果我们牢记这个方法:

那么,[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,我得到了这个结果:


(来源:subirimagenes.com

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

有什么想法吗?

我认为您正在寻找并行方法。 这就是work stealing algorithm was designed for, aka Fork Join Pool。事实上,质数计算是工作窃取的一个经典用例,因为判断 n 是否为质数需要迭代到 sqrt(n),所以 n 越大需要的时间越长。因此,将它们平均分配给您的工人并等待每个工人完成工作是不公平的,第一个核心将快速确定 n 是否为素数并闲置,另一个核心将忙于计算更大的数字。通过窃取工作,空闲处理器将从其邻居队列中窃取工作。

This implementation might be useful.

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

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