并行for循环可以写入公共矩阵吗?

时间:2012-12-07 19:09:27

标签: matlab parallel-processing

我不确定并行for循环的迭代是什么意思是独立的。以下是两个有效并行for循环的示例吗?它们写入和读取相同的矩阵,但矩阵索引对于每次迭代都是唯一的。

X = zeros(64);
parfor i = 1:64^2
    X(i) = i;
end
parfor i = 1:64
    X(i,:) = X(i,:) .* randn(1,64);
end

1 个答案:

答案 0 :(得分:4)

parfor而言,以下三个陈述可视为等同:

1)parfor循环的迭代必须是独立的。

2)parfor循环的迭代可能不依赖于任何其他迭代的结果。

3)parfor循环的迭代必须能够以任何顺序执行(来自@Oli)

这些陈述与常规循环相比如何?例如,在1到8的典型循环中,第4次迭代可能取决于迭代1,2和3,因为软件可以确定这些迭代在我们达到迭代次数4时已经发生。它必须不是取决于迭代5,6,7和8,因为软件可以确定这些迭代不会发生。

parfor循环中,如@Oli所述,循环可以按任何顺序发生。它们可以按以下顺序发生,例如,7 3 4 1 2 5 8 6.或者这8个数字的任何排列。这意味着非常重要的事情:在事先发生迭代的事实之前无法知道。要看到这一点,只需在fprintf('Up to iteration %d of %d\n', t, T)循环中放一个parfor,其中t是循环下标,T是循环上限。

上述陈述立即暗示了以下结论:由于任何迭代可能首先发生,因此任何迭代都不依赖于任何其他迭代的结果是至关重要的。我将用一些例子总结答案:

X = ones(8, 8)
parfor n = 1:8
    X(:,n) = X(:,n) .* (3 * ones(8,1));
end

在这个例子中,(3 * ones(8,1))显然不依赖于任何其他迭代 - 相对于循环计数器是恒定的。类似地,X(:, n)不依赖于除第n个之外的任何迭代。 编辑:我以前在上面的示例中使用randn - 请参阅@AndrewJanke提供的评论中的讨论,了解为什么这是一个坏主意。这种情况怎么样:

X = ones(8, 8);
parfor n = 1:8
    X(:,n) = X(:,n) + (n + 1);
end

这也完全有效。虽然表达式中有n + 1,但这与依赖于迭代编号n + 1不同。相反,它只是将当前迭代次数的整数值加1加到X

最后,请考虑:

X = ones(8, 1);
parfor n = 2:8
    X(n, 1) = X(n-1, 1) + 1;
end

这在常规循环中是完全有效的,因为迭代次数n-1将始终在迭代n之前发生(假设我们正在循环前进)。但是在parfor循环中,这将导致错误,因为迭代编号n可能在迭代编号n-1之前发生。 Matlab用来描述问题的术语叫做“切片”。想象一下,通过循环迭代将X切片。然后在第n次迭代中,您可能只会引用X的第n个切片。

最后一点,如果我对parfor循环有疑问,我会阅读文档中标题为“Matlab中的并行for循环 - 概述”的部分(抱歉,找不到相应的网页 - 对Matlab文档不常见)它描述了循环内所有可能的变量分类,以及parfor循环对每个分类的限制。我在这个答案中讨论的内容实际上只是冰山一角。例如,诸如n = n + 1之类的语句在parfor循环中也是无效的,因为n是循环变量,并且不允许对循环变量赋值。