Algorithm 均匀划分连续数列
在K个工作者之间连续并行N个令人尴尬的并行工作块的过程中,一项常见任务是使用以下算法以伪代码进行分区:Algorithm 均匀划分连续数列,algorithm,parallel-processing,partitioning,Algorithm,Parallel Processing,Partitioning,在K个工作者之间连续并行N个令人尴尬的并行工作块的过程中,一项常见任务是使用以下算法以伪代码进行分区: acc = 0 for _ in range(K): end = acc + ceil(N/K) emit acc:end acc = end 这将产生K个相邻分区,通常大小为N/K,适用于较大的N。但是,如果K大约为N,这可能会导致不平衡,因为最后一个工人将获得很少的项目。如果我们将不平衡定义为分区大小之间的最大绝对差异,那么从任意随机分区开始的迭代算法,如果K除以
acc = 0
for _ in range(K):
end = acc + ceil(N/K)
emit acc:end
acc = end
这将产生K个相邻分区,通常大小为N/K,适用于较大的N。但是,如果K大约为N,这可能会导致不平衡,因为最后一个工人将获得很少的项目。如果我们将不平衡定义为分区大小之间的最大绝对差异,那么从任意随机分区开始的迭代算法,如果K除以N,则减少潜力,直到最大差异为1或0,这将是最优的
在我看来,通过执行在线重新规划,以下可能是获得相同答案的更有效方法。这个算法有名字和最优性证明吗
acc = 0
workers = K
while workers > 0:
rem = N - acc
end = acc + ceil(rem/workers)
emit acc:end
acc = end
workers -= 1
编辑。考虑到我们可以递归地定义上面的循环,我可以看出归纳最优性证明可能有效。在任何情况下,其最佳性的名称和确认都是值得赞赏的:划分范围的简单方法是:
for i in range(K):
emit (i*N // K):((i+1)*N // K)
这具有自身可并行化的优点,因为迭代不需要按顺序执行
很容易证明每个分区都有floorN/K或ceilN/K元素,很明显,每个元素都正好位于一个分区中。由于地板和天花板最多相差1,因此算法必须是最优的
你建议的算法也是最优的,结果也很相似。不过我不知道它的名字
可以并行划分范围的另一种方法是使用范围startN,K,i:startN,K,i+1,其中startN,K,i是N//K*i+mini,N%K。注意,N//K和N%K只需要计算一次。该算法也是最优的,但分配了不平衡,因此第一个分区是较大的分区。这可能有用,也可能无用。这里有一个更简单的方法。您有可以在工作人员之间完美划分的所有/K个任务,剩下N个mod K个任务。要保持区域连续,可以将剩余的任务放在前N个mod K worker上 这里是命令式的。为了清楚起见,我正在为任务{0..N-1}编号,并发出一组连续的任务编号
offset = 0
for 0 <= i < K:
end = offset + floor(N/K)
if i < N mod K:
end = end + 1
emit {c | offset <= c < end}
offset = end
以更具陈述性的风格:
chunk = floor(N/K)
rem = N mod K
// i == worker number
function offset(i) =
i * chunk + (i if i < rem else rem)
for 0 <= i < K:
emit {c | offset(i) <= c < offset(i+1)}
在这一点上,最优性的证明是相当琐碎的。Worker i分配了offseti+1-offseti任务。取决于i,这是floorN/K或floorN/K+1任务