Matlab 如何为嵌套循环设置“parfor”?

Matlab 如何为嵌套循环设置“parfor”?,matlab,parallel-processing,parfor,Matlab,Parallel Processing,Parfor,原始代码如下所示: for i = 1 : size(H, 1) for j = 1 : size(H, 2) H{i,j} blabla parfor ind = 1 : numel(H) [i, j] = ind2sub(ind); H{i,j} blabla 我尝试将其改编成并行代码,如下所示: for i = 1 : size(H, 1) for j = 1 : size(H, 2) H{i,j} blabla par

原始代码如下所示:

for i = 1 : size(H, 1)
    for j = 1 : size(H, 2)
        H{i,j} blabla
parfor ind = 1 : numel(H)
    [i, j] = ind2sub(ind);
    H{i,j} blabla
我尝试将其改编成并行代码,如下所示:

for i = 1 : size(H, 1)
    for j = 1 : size(H, 2)
        H{i,j} blabla
parfor ind = 1 : numel(H)
    [i, j] = ind2sub(ind);
    H{i,j} blabla
这将生成一个错误,说明由于H{i,j}无法运行
parfor

那么这里的错误是什么?如何将嵌套循环调整到parfor?

一种可能的解决方案是

for i = 1 : size(H, 1)
    parfor j = 1 : size(H, 2)
        H{i,j} blabla

但是我怀疑在另一个循环中使用parfor会增加parfor的开销,这会导致额外的计算时间,我认为使用parfor的错误在于Matlab无法检测到
[I,j]
在循环中是唯一的,因为它是一个函数的结果。因此,对于引擎,您可以多次访问
H{i,j}
,迭代不会被分析为彼此独立

编辑:正如patrik所提到的,您必须确保两次迭代之间没有依赖关系,也就是说,
H{i,j}
不依赖于
H{k,l}
i=k和j=l
,也不会在另一次迭代中使用迭代中的变量值。此要求是允许parfor的基本要求,但来自的要求除外

除此之外,如果您想并行运行独立计算,并且值得,请始终选择最外层的循环。除此之外,提醒,;相反,如果要并行化内部for循环,则必须生成一个运行
parfor
的函数。内部循环的并行化可能不会带来加速(取决于parpool中有多少工人)

根据我的经验,不建议运行并行内部循环。作为一个例子(在Matlab之外),我要引用LibSVM,它建议如果您想加快计算速度,只使用openmp并行最外层的循环,而不并行其他内部循环

此建议的原因是您的工作线程池有限,工作线程可能被视为线程;如果添加线程,由于在线程之间切换的时间有限,计算运行速度会变慢。Matlab可以很好地管理这一部分,但关键是您将有一个有限规模的工作人员池。如果每一个最外层的迭代都需要很多时间,并且有很多迭代,那么您将没有时间并行化内部循环,因为每个工作人员都将忙于运行整个迭代(包括内部循环)


尽管如此,测试每个选项总是一件好事,其中一些选项可能会反直觉地更适合您的问题

为什么不简单地使用线性索引分配到H中?例如:

H = cell(4, 4);
parfor idx = 1:16
  [i, j] = ind2sub([4, 4], idx);
  H{idx} = rand(i, j); % or whatever
end
否则,最好将最外层的循环设为PARFOR循环。以下方法也有效:

H = cell(4, 4);
parfor r = 1:4
  for c = 1:4
    H{r, c} = rand(r, c);
  end
end

我怀疑
H{I,j}blablabla
可能以某种方式修改了您的单元格数组
H
——在这种情况下,当您尝试并行运行时,您不知道哪些修改已经发生或尚未发生。在单元格数组
H
下,您到底有哪些修改,即
H{I,j}
?比如我们在处理什么样的数据?你有没有尝试过
parforind=1:numel(H),H{ind}blabla,end
?这应该没问题。目前我正在研究一个类似@Daniel's comment的解决方案。但是,某个线程在某个点停止,这会导致程序完全失败。还应该指出,不存在任何内部依赖关系,例如
H{i,j}
不能依赖
H{k,l}
k~=i,l~=l
这可能导致程序停止:例如,如果线程A需要在线程B启动之前完成,线程B需要在线程A启动之前完成。这当然是你提到的,但在这种情况下,我想这应该被明确提到。@patrik这确实值得注意,我想这不是OP中的情况。我现在编辑我的答案以增加精确度,thk