【问题标题】:Using struct arrays in parfor在 parfor 中使用结构数组
【发布时间】:2013-05-21 11:56:50
【问题描述】:

我在 Matlab 的 parfor 循环中使用结构数组时遇到问题。以下代码有2个问题我不明白:

s=struct('a',{},'b',{});
if matlabpool('size')==0
  matlabpool open local 2
end

for j = 1:2      
  parfor k=1:4
    fprintf('[%d,%d]\n',k,j)
    s(j,k).a = k;
    s(j,k).b = j;
  end
end
matlabpool close
  1. 失败并出现错误Error using parallel_function (line 589) Insufficient number of outputs from right hand side of equal sign to satisfy assignment.
  2. 在输出时,变量 s 是一个向量,而不是一个数组(应该是这样,即使代码在完成之前中断)。

编辑如果我将结构数组初始化为正确的大小,问题就解决了,方法是:

s=struct('a',cell(2,4),'b',cell(2,4));

但是,我仍然很乐意获得有关该问题的见解(例如,它是否像 Oleg Komarov 所建议的那样集结了一个错误)

【问题讨论】:

  • 对于第 2 点,“数组”而不是“向量”是什么意思?在 Matlab 中没有区别。在我看来,s 应该是这段代码末尾的 structs 的 2x4 矩阵。
  • 我认为这实际上是一个错误,我建议提交support equest 并让我们保持更新。
  • @jazzbassrob,向量是一个 1xd 数组(或 dx1)。

标签: matlab parallel-processing


【解决方案1】:

它最初对我来说很好,但后来我不知道会发生什么。一般来说,您需要小心使用 parfor 循环,并且有大量关于如何对齐所有内容的文档。两种不同的忠告。 首先也是更重要的是,parfor 循环位于外部循环中:

function s = foo
s=struct('a',{},'b',{});

parfor j = 1:2      
  for k=1:4
    fprintf('[%d,%d]\n',k,j)
    s(j,k).a = k;
    s(j,k).b = j;
  end
end

第二,Matlab 对编写主出口变量非常挑剔(即包含在 parfor 循环中的变量,它被索引到循环,在你的情况下,s)。您首先要创建一个包含所有内部循环信息的虚拟变量,然后在循环结束时写入一次。示例:

function s = khal
s=struct('a',{},'b',{});


parfor j = 1:2 
   dummy=struct('a',{},'b',{});
  for k=1:4
    fprintf('[%d,%d]\n',k,j)
    dummy(k).a = k;
    dummy(k).b = j;
  end
  s(j,:) = dummy;
end

这里没有问题,但在其他情况下可能会变得复杂

【讨论】:

  • 为什么 parfor 应该在外循环中?如果我在索引 [1,2] 上有外循环,在索引 [1,...,1000] 上有内循环,则更长的内循环不会被并行化,是吗?
  • 拥有 parfor 循环会产生间接成本,并且在某些情况下,将其置于内部循环中会具有成本效益(特别是如果您有两个以上的池正在运行),但通常,您应该构造代码,使 parfor 循环位于外循环中。如果池为 2,则在外循环中使用 parfor 几乎总是更快(尝试并比较...)。
  • 好答案!不知何故,如果您使用parfor loop(在本例中为j)的切片变量来索引原始结构,它就可以工作。以任何其他方式建立索引似乎都不起作用。例如,s(1,:) 不起作用,但 s(j,:) 起作用!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-17
  • 1970-01-01
  • 1970-01-01
  • 2012-05-02
相关资源
最近更新 更多