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