在外部使用parfor的双循环错误

时间:2016-06-07 08:33:33

标签: matlab loops parallel-processing parfor

我需要并行化代码以节省时间。我有一个内部循环的循环,我想并行外部循环(因为我认为这样代码更快)。我的代码如下所示:

A = rand(1000,1);
B = rand(1000,1);
Biggers = zeros(1000,1000);
parfor i = 1:size(A,1)
    for j= 1:1:size(B,1)
        if B(i,1) > A(j,1) 
           Biggers(i,j) = A(j,1);
        end
     end
end

但如果我这样运行,我会收到错误:

Error: The variable Biggers in a parfor cannot be classified.   
See Parallel for Loops in MATLAB, "Overview".

如果我改为并行化内部循环,即如果将代码设计为:

,则不会发生这种情况
A = rand(1000,1);
B = rand(1000,1);
Biggers = zeros(1000,1000);
for i = 1:size(A,1)
    parfor j= 1:1:size(B,1)
        if B(i,1) > A(j,1)
            Biggers(i,j) = A(j,1);
        end
    end
end

我不明白为什么在第一种情况下Biggers不被视为切片变量,因为每个工作者应该只关注我变量的一行。

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

至于为什么它不适用于外循环我不确定。 MATLAB对parfor循环中哪些内容可以和哪些内容都没有严格的规定有非常严格的规定。

“简单”的解决方案是将里面你的parfor循环中的所有内容包装成一个函数,然后parfor突然吃掉所有内容。即。

function Biggers = parforfunc(A,B,ii)
for jj= 1:size(B,1)
    if B(ii,1) > A(jj,1) 
       Biggers(ii,jj) = A(jj,1);
    end
end
end

将其另存为parforfunc.m并使用

运行您的脚本
A = rand(1000,1);
B = rand(1000,1);
Biggers = zeros(size(B,1),size(A,1));
parfor ii = 1:size(A,1)
    Biggers = parforfunc(A,B,ii);
end

答案 1 :(得分:3)

@Adriaan的回答巧妙地解决了这个问题 - 但是如果你很好奇,那么这里的问题就是内部for循环的“非常数”界限。您和我可以清楚地看到内部for循环的边界在实践中是不变的,但MATLAB的parfor规则要求任何内部for循环的边界都是“广播”变量。所以,修复是微不足道的 - 将内循环边界计算提升到parfor循环之外,如下所示:

A = rand(1000,1);
B = rand(1000,1);
Biggers = zeros(1000,1000);
n = size(B,1);
parfor i = 1:size(A,1)
    for j= 1:n
        if B(i,1) > A(j,1) 
           Biggers(i,j) = A(j,1);
        end
    end
end

此案例描述为in the doc