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