准备并行运行代码
在创建适合并行运行的代码的过程中,有时我们使用带有
为
-循环,并简单地将其替换为一个并行循环,使用
parfor
.也就是说,如果我们不能首先很好地向量化代码。这种从
为- - - > parfor
有时候真的很有效,但并不总是有效,原因很充分。
例如,你不能简单地替换
为
与
parfor
如果循环迭代不是完全独立的。你可以找到更多的条件
在这里
.这条规则有一个明显的例外,
减少变量
(一个
减少变量
累计一个依赖于所有迭代的值,但与迭代顺序无关)。这方面的文档非常棒。下面是一个快速的伪代码,它可以很好地并行化,即使我们重用了变量
年代
在右边和左边。只要结果在数值上对累加发生的顺序不敏感,无论使用a,您都将得到“正确”的答案
为
或者一个
parfor
循环。
S = 0;
parforInd = 1:100
S = S + fun(数据(ind));
结束
测试并行性
我怀疑并行性是一个词,但我想你知道我的意思!
查看您的循环是否适合并行化的一个简单方法是尝试以另一种顺序运行循环,看看是否得到相同的结果。如果是,它是一个候选
parfor
.最简单的版本可能是反向运行循环。如果您得到与标准扫描相同的结果,那么您应该可以开始了。除了反向,你还可以尝试用计数器随机顺序替换循环;这可以很容易地实现
randperm
.
注:显然,这个计算可以很容易地向量化。这不是我的重点。
K = randn(100,1);
均值=均值(k);
Tol =根号(eps);
Qforward = 0 (size(k));
为Ind = 1:100
Qforward (ind) = k(ind) -均值;
结束
均值=均值(k);
Qbackward = 0 (size(k));
为Ind = 100:-1:1
Qbackward (ind) = k(ind) -均值;
结束
均值=均值(k);
Qrandom = 0 (size(k));
为Ind = randperm(100)
Qrandom (ind) = k(ind) -均值;
结束
Aretheyequal = isequal(qforward, qbackward, qrandom)
如果答案不完全相等,你可以用类似的方法来比较它们。
Nearlyfb = norm(qforward-qbackward) < tol
Nearlyfr = norm(qforward-qrandom) < tol .
Nearlybr = norm(qback -qrandom) < tol
这个计算是可以尝试的
parfor
.
Qpar = 0 (size(k));
为Ind = 1:100
Qpar (ind) = k(ind) -均值;
结束
Aretheyequal = isequal(qpar, qforward)
如果我有一个迭代依赖的表达式
您可能不总是能够并行化您的代码。但是,在某些条件下,您可以通过稍微重构您的计算来转换您的代码以利用并行化。在本例中,我将在循环完成后进行一些积累。
代码分析器给第一个代码块两个红色错误消息。
X = [17 0 (1,99)];
K = [0 randn(1,99)];
parforInd = 2:100
X (ind) = X (ind-1) + k(ind)^2;
结束
%%来自以上代码的错误消息:
的由于变量'x'的使用方式,PARFOR循环无法运行。
在PARFOR循环、变量'x'有不同的索引方式,有可能
导致迭代之间的依赖关系。
这是
为
循环等效,无警告。
X = [17 0 (1,99)];
K = [0 randn(1,99)];
为Ind = 2:100
X (ind) = X (ind-1) + k(ind)^2;
结束
Xx = x;
这就是并行化的方法
X = [17 0 (1,99)];
TMP = 0 (1100);
parforInd = 2:100
Tmp (ind) = k(ind)^2;
结束
X = cumsum(X +tmp);
Aretheyequal = isequal(x,xx)
想法吗?
您是否经常处理大型数据集或模拟,从而访问适合并行运行代码的硬件有助于您的工作扩展?你的代码是否属于我在这篇文章中提到的简单类别?我很乐意听到您关于将代码转换为适合并行化的形式的任何问题。发表你的想法
在这里
.