MATLAB parfor循环简介
一、决定何时使用parfor循环
如果有以下情况,考虑采用parfor循环:
- 一些需要执行很长时间的循环迭代。在这种情况下,workers可以同时执行长迭代。
- 简单计算的多次循环迭代,例如蒙特卡罗模拟或参数扫描。parfor将循环迭代分成几组,每个worker执行总迭代次数的一部分。
如果有以下情况,parfor循环可能没有用:
- 以矢量化输出的for循环。一般来说,如果想让代码运行得更快,首先尝试对其进行矢量化,矢量化代码能够受益于许多底层MATLAB库的多线程特性所提供的内置并行性。但是,如果有矢量化代码并且只能访问本地的worker,那么 parfor-loops 可能比 for-loops 运行得慢。
- 只需要很短执行时间的循环迭代。在这种情况下,并行开销主导了计算。
当循环中的迭代取决于其他迭代的结果时,不能使用parfor-loop 。每次迭代都必须独立于所有其他迭代。
二、低并行开销的例子
该示例计算了矩阵的谱半径,并将一个for循环转换为parfor循环。了解如何测量由此带来的加速,以及并行池中的worker有多少数据量传入传出。
tic
n = 200;
A = 500;
a = zeros(n);
for i = 1:n
a(i) = max(abs(eig(rand(A))));
end
toc
以上for循环经历了31.935373秒
tic
ticBytes(gcp);
n = 200;
A = 500;
a = zeros(n);
parfor i = 1:n
a(i) = max(abs(eig(rand(A))));
end
tocBytes(gcp)
toc
以上parfor循环经历了10.760068秒
当前示例的并行开销较低,并且受益于parfor-loop的转换。
三、高并行开销的例子
此示例编写一个循环来创建一个简单的正弦波。此循环没有很多迭代,执行时间不长,执行速度的提高不显著。此示例具有高并行开销,并且无法从转换为parfor-loop 中获益。
tic
n = 1024;
A = zeros(n);
for i = 1:n
A(i,:) = (1:n) .* sin(i*2*pi/1024);
end
toc
以上for循环经历了0.012501秒
tic
ticBytes(gcp);
n = 1024;
A = zeros(n);
parfor (i = 1:n)
A(i,:) = (1:n) .* sin(i*2*pi/1024);
end
tocBytes(gcp)
toc
以上parfor循环经历了0.743855秒
注意到串行loop的运行时间比四个worker的并行loop运行时间要小得多,原因是数据的传输比前面的例子要多得多