我有一大堆任务对象。 大多数任务都有父母任务 - 之前需要执行的。 大多数任务都有子任务 - 只能在之后执行。 关键是这样一组任务对象,一旦创建就经常执行 并且应该通过并行执行任务来利用所有可用的CPU。 我遇到的问题是与任务对象相关的工作量通常不是太小 - 调度代码只处理自身 - 要完成的实际工作不会显示在分析结果中( GRIN)。 任务对象确实提供了成本函数! 我在考虑创建另一组任务对象, 每个新任务对象包含旧任务对象的集合。 这些新任务对象引用的父母和子女当然也应该是新的任务对象。 这会通过降低并行性来减少必要的通信。
显然,将旧任务结合到新任务中的方法越来越好......
有人会想到这样做的算法吗? 我重新发明了轮子吗?
答案 0 :(得分:0)
您似乎拥有的是对要执行的一组任务的部分顺序,其中前任任务必须在后续任务运行之前完成。
如果您测量任务T2执行的成本,并且它小于调度开销,那么您可以考虑优化它。
如果它只有一个前驱T1(只需将其代码插入前一个T1的末尾,并将前任T1链接到T2的后继)或只有一个后继T3(只需将其代码插入到其中),就可以轻松完成此操作继承者T3的开头,并将T2的前辈链接到T3)。
假设你有
(;| 1 (<< 2 4) a
2 b
3 (<< 4) c
4 d )
(部分命令PARLANSE程序,任务1 2 3 4分别由工作abcd组成,任务1发生在任务2和4之前,任务3发生在4之前。有趣的操作符“; |”由部分命令混合驱动串行“;”和并行“|”计算。有趣的运算符(&lt;&lt; nm)意味着“比n和m更早地运行”。 请注意,任务1和3可以并行运行; 2和3以及2和4也是如此。[这是可以表达的最小的部分顺序,它不是纯粹的平行]。
如果b太小,您可以将其优化为:
(;| 1 (<< 4) (;; a b)
3 (<< 4) c
4 d )
其中a和b是连续执行的。
如果它有多个前辈和后继者,那就不那么容易了。你可以利用的是,任何偏序计算都有许多完全合法的线性化。在这种情况下,您基本上希望收集一组过于廉价的任务,这些任务在其中一个序列中是线性的,并通过线性化替换它们。
想象一下任务4太小了。因为b c d是部分顺序的有效线性化,所以可以组合任务c和d:
(;| 1 (<< 2 3) a
2 b
3 (;; c d) )
如果极端的话,这个过程将序列化所有计算,如果它们的成本很小,那就完全是你想要的那样。