MATLAB问题中的Parfor



为什么我不能在这段代码中使用parfor ?

parfor i=1:r
    for j=1:N/r
        xr(j + (N/r) * (i-1)) = x(i + r * (j-1));
    end
end

错误:

错误:parfor中的变量xr无法分类。参见MATLAB中的并行循环,"概述"。

这里的问题是切片数组的索引不正确。parfor循环异步运行,这意味着每次迭代执行的顺序是随机的。来自文档:

MATLAB工作器评估迭代没有特定的顺序,并且彼此独立。因为每个迭代都是独立的,所以不能保证迭代以任何方式同步,也没有必要这样做。

您可以通过在命令行中输入以下命令轻松验证上述语句:

parfor i=1:100
    i
end

你会发现顺序是任意的。因此,如果在不同的worker之间拆分并行作业,则一个worker无法判断不同的迭代是否已经完成。因此,变量索引不能依赖于迭代器的过去/未来值。

让我用一个简单的例子来说明。考虑斐波那契数列1,1,2,3,5,8,...。您可以轻松地生成该序列的前10项(在naïve for循环中):

f=zeros(1,10);
f(1:2)=1;
for i=3:10
    f(i)=f(i-1)+f(i-2);
end

现在让我们对parfor循环做同样的操作。

f=zeros(1,10);
f(1:2)=1;
parfor i=3:10
    f(i)=f(i-1)+f(i-2);
end

? ?错误:parfor中的变量f无法分类。参见MATLAB中的并行循环,"概述"

但是为什么会出现错误呢?

我已经展示了迭代以任意顺序执行。因此,假设一个worker获得循环索引i=7和表达式f(i)=f(i-1)+f(i-2);。现在应该执行表达式并将结果返回给主节点。现在迭代i=6完成了吗?存储在f(6)中的值可靠吗?f(5)呢?你明白我的意思了吗?假设f(5)f(6)没有完成,那么您将错误地计算出斐波那契级数的第7项是0!

由于MATLAB无法告诉您的计算是否可以保证正确运行并每次都重现相同的结果,因此明确不允许这种模棱两可的赋值。

最新更新