我正在开发一个多线程程序,我有许多工作线程执行不等长的任务。我想对任务进行负载平衡,以确保它们完成大致相同的工作量。对于每个任务T i 我有一个数字c i ,它提供了该任务所需工作量的良好近似值。
我正在寻找一个有效的(O(N)N =任务数或更好的)算法,这将给出“大致”给定c i 的值的良好负载平衡。它不一定是最优的,但我希望能够对结果分配的糟糕程度有一些理论界限。
有什么想法吗?
答案 0 :(得分:7)
您想要实施work stealing algorithm。每个工作线程都有一个双端队列,新任务被添加到最小队列的底部。工作人员从他们自己的队列顶部删除任务(顶部/底部分离减少争用),当一个工人没有更多的工作要做时,它会从最大队列的底部窃取一个工作。这很简单,效果很好,这是微软并行系统.net4.0的基础上我认为的算法。
结果分配非常好,如果整个系统中没有更多可用的作业,工作线程将无需做任何工作。
的Nb。如果你想要一些示例代码拆开,我的朋友写了一个C#的工作窃取系统,你可以找到here
答案 1 :(得分:3)
我倾向于不提前弄清楚如何分配任务,而是将它们全部扔进一个共同的工作队列。任何没有其他事情要做的工作线程都会抓住队列中的下一个任务来完成工作并检查队列中的下一个任务。
答案 2 :(得分:2)
最简单的方法是按p_i降序排序(但这是O(n log n))并执行此操作:
该算法应该给你最好的结果但是有O(N M)时间,其中N是任务数和M个线程数。溶液的总成本是O(N log N + N M),因此M <&lt;&lt;&lt; N为O(N log N),N附近的M为O(n ^ 2)。
答案 3 :(得分:1)
在O(N)中,这似乎很容易。
给每个帖子一些“点”。让p_i
分配给线程T_i
的点。对于每项任务,请选择p_i
最高的主题,并从p_i
中减去任务费用。然后,您只需要跟踪按分数排序的线程,这在O(N)时间内是微不足道的,并且可以使用平衡树在O(log N)中轻松完成。
对于连续操作,p_i
中没有最小值。如果你想避免分数流向-inf,只需定期为所有分数添加任意数量P
(所有分数的数量相同)。
编辑:我错了N.上面,N是线程数,与问题相反。当N =任务数,并且T =线程数时,这导致O(N * log T)成本。如果T为“小”,则接近O(N)。
编辑2:如果事先知道所有任务以及线程数,那么我认为计算最佳调度类似于knapsack problem,它是,一般来说,NP-complete(所以你会在某处获得指数)。只要所有单个任务在分配给每个线程的总成本方面的成本很小,上面以某种方式描述的基于成本的简单分析就会给你一个相对较好的近似值。
答案 4 :(得分:1)
答案 5 :(得分:1)
虽然有关背包问题的建议很有帮助,但您说您正在尝试最小化执行的净时间。采用背包方法需要你不断增加你的背包尺寸,直到你得到一个可行的解决方案 - 效率不高。
如果执行的净执行时间受到并行工作的所有线程中最长完成时间的限制,我想分配任务,以便最小化所有线程的MAXIMUM工作时间。这样做可能会导致一个或多个线程无法完成大量工作,因此我们并没有真正“平衡”工作。如果你想平衡工作,那么这是一个不同的目标函数。例如,您可能希望最小化线程之间的工作差异。
查看作业车间调度区域。如果您不经常这样做,我建议使用遗传算法 - 如果您必须经常以更自动化的方式进行,我建议您做一些文献搜索确定性算法。希望这可以帮助。