And*_*eas 6 parallel-processing matlab
我不确定并行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
Run Code Online (Sandbox Code Playgroud)
就目前parfor而言,以下三种说法可以认为是等价的:
1)循环的迭代parfor必须是独立的。
2)parfor循环的迭代不能依赖于任何其他迭代的结果。
3)循环的迭代parfor必须能够以任何顺序执行(来自@Oli)
这些语句与常规循环相比如何?例如,在从 1 到 8 的典型循环中,第四次迭代可能取决于迭代 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
Run Code Online (Sandbox Code Playgroud)
在此示例中,(3 * ones(8,1))显然不依赖于任何其他迭代 - 相对于循环计数器而言是恒定的。同样,X(:, n)不依赖于第 n 次以外的任何迭代。编辑:我之前在上面的示例中使用过randn- 请参阅@AndrewJanke 提供的评论中的讨论,了解为什么这是一个坏主意。这种情况怎么办:
X = ones(8, 8);
parfor n = 1:8
X(:,n) = X(:,n) + (n + 1);
end
Run Code Online (Sandbox Code Playgroud)
这也是完全正确的。虽然表达式中有一个n + 1,但这与取决于迭代次数不同n + 1。相反,它只是将当前迭代次数的整数值加 1 分配给X。
最后,考虑:
X = ones(8, 1);
parfor n = 2:8
X(n, 1) = X(n-1, 1) + 1;
end
Run Code Online (Sandbox Code Playgroud)
这在常规循环中是完全有效的,因为迭代次数n-1总是在迭代之前发生n(假设我们向前循环)。但在parfor循环中,这会导致错误,因为 iteration numbern可能出现在 iteration number 之前n-1。Matlab 用来描述该问题的术语称为“切片”。想象一下X被循环迭代分割。然后在第 n 次迭代中,您可能只引用 的第 n 个切片X。
最后一点,如果我对循环有疑问parfor,我会阅读文档中标题为“Matlab 中的并行 for 循环 - 概述”的部分(抱歉,找不到相应的网页 - 对于 Matlab 文档来说不常见)它描述了所有内容循环内可能的变量分类,以及循环parfor对每个分类的限制。我在这个答案中讨论的实际上只是冰山一角。例如,诸如 之类的语句n = n + 1在循环中也是无效的parfor,因为n是循环变量,并且不允许对循环变量进行赋值。