我不确定这意味着什么平行for循环的迭代是独立的。下面是两个有效的并行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
我不确定这意味着什么平行for循环的迭代是独立的。下面是两个有效的并行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
至于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个数字的任何排列。这意味着一件非常重要的事情:在首先发生迭代的事实之前没有办法知道。要看到这个,只需在parfor
循环内查找fprintf('Up to iteration %d of %d\n', t, T)
,其中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
循环有任何疑问,请阅读文档中标题为“Parallel for loops in Matlab - overview”的文档中的部分(对不起,无法找到相应的网页 - 对于Matlab很不寻常文档)它描述了循环内的所有可能的变量分类,以及每个分类上循环的限制。我在这个答案中讨论的只是冰山一角。例如,n = n + 1
等语句在parfor
循环中也无效,因为n
是循环变量,并且不允许对循环变量进行赋值。
嗯。你知道,'randn'可能是一个不好的例子,因为它对Matlab的全局状态有副作用。这是一个PRNG,每个Matlab会话以相同的随机种子开始;每个“randn”调用都会促进它的发展。所以它的输出取决于以前的循环迭代; 'randn'的输出是该会话中被调用了多少次的函数。每个工人都是一个会话,所以这段代码的结果将直接取决于有多少员工,循环运行的顺序以及还有哪些会影响这些会话的'rng'状态。 –
也就是说,我认为使用randn违反了“任何迭代都不依赖于任何其他迭代的结果”这个规则是非常重要的,因为调用randn的迭代的一部分结果是rng是高级的,这是对'randn'的隐藏输入。这是parfor检查无法捕捉的不确定性,因此人类程序员需要避免或确保非确定性“无关紧要”。这里要做的“正确的”事情可能是在“parfor”之前生成整个rand块,然后在循环迭代中切入它;那么你会有可重复性。 –
@AndrewJanke我没有想到这一点!非常聪明!我相应地调整了答案以删除randn。我认为这只会让读者很难把大多数随机数发生器的固有决定论的讨论纳入上面的答案。 –
如果Matlab不是有效的并行循环,则会输出一个错误。所以,你只需要在matlab中运行它,你就可以马上得到答案。 – Oli
来自docs的引用似乎表明,Matlab并不总是警告:“注意由于迭代顺序的独立性,parfor的执行并不能保证确定性结果。” – Andreas
这只是意味着迭代可以按任何顺序完成。这对你的情况没有影响。 – Oli