【问题标题】:Matlab parallel computing toolbox, dynamic allocation of work in parfor loopsMatlab并行计算工具箱,parfor循环中的动态分配工作
【发布时间】:2012-03-30 04:55:10
【问题描述】:

我正在 matlab 中处理一个长时间运行的 parfor 循环。

parfor iter=1:1000
   chunk_of_work(iter);
end

每次运行通常大约有 2-3 个计时异常值。也就是说,每执行 1000 个工作块,就有 2-3 个工作块花费的时间大约是其余部分的 100 倍。随着循环接近完成,评估异常值的工作人员继续运行,而其余工作人员没有计算负载。

这与 parfor 循环静态分配工作是一致的。这与并行计算工具箱found here的文档形成鲜明对比:

“工作分配是动态的。而不是被分配一个固定的 迭代范围,只有在 他们完成了当前迭代的处理,这导致了 平均工作量分配。”

对正在发生的事情有什么想法吗?

【问题讨论】:

    标签: matlab parallel-processing load-balancing


    【解决方案1】:

    我认为您引用的文档很好地描述了什么是静态工作分配:每个工作人员“被分配了一个固定的迭代范围”。对于 4 名工作人员,这意味着第一个被分配 iter 1:250,第二个被分配 iter 251:500,... 或者第一个分配 1:4:100,第二个分配 2:4:1000 和以此类推。

    您没有准确说出您观察到的内容,但您所描述的内容与动态工作负载分布非常一致:首先,四个(示例)工作人员每个工作一个 iter,第一个完成的工作在第五个工作,下一个完成(如果前四个中的三个需要更长的时间,这很可能是相同的)在第六个上工作,依此类推。现在,如果按照 MATLAB 选择处理循环迭代的顺序,您的异常值是数字 20、850 和 900,并且每次都需要 100 倍的时间,这仅意味着第 21 到第 320 次迭代将由四个工作人员中的三个解决,而一个是忙于 20 日(到 320 年将完成,现在假设非异常值计算时间的分布大致均匀)。然而,即使在另一个解决了#1000 之后,分配给第 850 次迭代的工作人员仍将继续运行,对于 #900 也是如此。事实上,如果有大约 1100 次迭代,那么在 #900 上工作的那个应该大致在其他迭代完成的时候完成。

    [已编辑,因为原始措辞暗示 MATLAB 仍会按从 1 到 1000 的顺序分配 parfor 循环的迭代,不应假定]

    长话短说,除非您首先找到一种处理异常值的方法(这当然需要您先验地知道哪些是异常值,并找到一种方法让 MATLAB 使用这些开始 parfor 循环处理) ,仅靠动态工作负载分配无法避免您观察到的效果。

    补充:但是,我认为,您观察到“随着循环接近完成,评估异常值的工作人员*s* 继续运行”似乎暗示了以下至少一项

    1. 异常值不知何故是 MATLAB 开始处理的最后一次迭代
    2. 您有很多工作人员,按迭代次数的数量级计算
    3. 您对异常值 (2-3) 数量的估计或对它们的计算时间损失(因子 100)的估计过低

    【讨论】:

      【解决方案2】:

      PARFOR 中的工作分配具有一定的确定性。您可以通过让每个工作人员将事情的进展情况记录到磁盘来精确观察正在发生的事情,但基本上事实证明,PARFOR 以一种确定性的方式将您的循环分成多个块,但动态地将它们分流。不幸的是,目前没有办法控制这种分块。

      但是,如果您无法预测 1000 个案例中的哪些会是异常值,则很难想象一个有效的分配工作方案。

      如果您可以预测异常值,您也许可以利用这样一个事实,粗略地说,PARFOR 以相反的顺序执行循环迭代,因此您可以将它们放在循环的“末尾”,以便开始处理它们马上。

      【讨论】:

        【解决方案3】:

        @arne.b 的回答很好地描述了您面临的问题,对此我没有什么要补充的。

        但是,并行计算工具箱确实包含用于分解 job into tasks 以供独立执行的函数。根据您的问题,无法得出这适合或不适合您的应用的结论。如果是,一般的策略是将作业分解成一定大小的任务,让每个处理器处理一个任务,完成后返回未完成任务的堆栈并开始另一个任务。

        您可能能够分解您的问题,以便一项任务替换一次循环迭代(大量任务,管理计算的大量开销,但最好的负载平衡),或者一项任务替换 N 次循环迭代(更少的任务,更少的开销,更差的负载平衡)。作业和任务也比parfor 更难实现。

        【讨论】:

          【解决方案4】:

          作为 PARFOR 的替代方案,在 R2013b 及更高版本中,您可以使用 PARFEVAL 并以您认为合适的任何方式分配工作。一旦获得足够的结果,您甚至可以取消“时间异常值”(如果合适的话)。当然,将现有循环划分为 1000 个单独的远程 PARFEVAL 调用时会产生开销。也许这是一个问题,也许不是。这是我想象的那种事情:

          for idx = 1:1000
               futures(idx) = parfeval(@chunk_of_work, 1, idx);
          end
          done = false; numComplete = 0;
          timer = tic();
          while ~done
              [idx, result] = fetchNext(futures, 10); % wait up to 10 seconds
              if ~isempty(idx)
                  numComplete = numComplete + 1;
                  % stash result
              end
              done = (numComplete == 1000) || (toc(timer) > 100);
          end
          % cancel outstanding work, has no effect on completed futures
          cancel(futures);
          

          【讨论】:

            猜你喜欢
            • 2011-10-29
            • 1970-01-01
            • 1970-01-01
            • 2011-11-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-08-21
            相关资源
            最近更新 更多