用线程获取素数。如何划分区间?
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 是否为素数并闲置,另一个核心将忙于计算更大的数字。通过窃取工作,空闲处理器将从其邻居队列中窃取工作。
我解决了这个问题。我没有对我的间隔进行第一次完整划分,并将每个部分分配给不同的服务器。我决定将区间分成非常小的部分(例如 [min, max]/length^2
),每个微积分服务器都得到这些部分之一。当他们完成后,他们会得到另一个,直到没有更多的小间隔可以计算。
我为什么要这样做?这是因为我无法确保我正在使用的服务器具有相同的微积分速度。
我想获取[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 是否为素数并闲置,另一个核心将忙于计算更大的数字。通过窃取工作,空闲处理器将从其邻居队列中窃取工作。
我解决了这个问题。我没有对我的间隔进行第一次完整划分,并将每个部分分配给不同的服务器。我决定将区间分成非常小的部分(例如 [min, max]/length^2
),每个微积分服务器都得到这些部分之一。当他们完成后,他们会得到另一个,直到没有更多的小间隔可以计算。
我为什么要这样做?这是因为我无法确保我正在使用的服务器具有相同的微积分速度。