我需要并行化代码以节省时间。我有一个内部循环的循环,我想并行外部循环(因为我认为这样代码更快)。我的代码如下所示:
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
不被视为切片变量,因为每个工作者应该只关注我变量的一行。
我该如何解决这个问题?
答案 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。