Arranged By Zhonglihao @ 2018
**请确认Matlab安装时点选了并行计算工具箱
第一章:parfor循环并行计算
parfor循环介绍
parfor循环是Matlab并行计算工具箱用于并行计算单循环的工具,并行度与CPU所具备的核心数有关,一般来说,经过处理的for循环都能够改为parfor循环以提高并行处理速度。Matlab中的CPU并行处理功能如下图所示进行开启,开启后也可以查看您的计算机具备多少个物理核心数(不支持超线程逻辑内核处理):
图1-1 点击Matlab软件左下角中图标
按”Start parallel pool”开启CPU多核并行计算
图1-2 图标显示蓝色条纹代表
处理器多核并行计算已启用
哪些场合适合和不适合开启并行计算:
·某些子循环所需要的计算量与其他子循环的计算量并不很相近,造成处理器需要等待最慢的一个自循环完成以继续同步物理核心,这种情况下使用并行没有很大的意义;
·一些简单的子循环例如蒙特卡洛仿真或参数扫描,这种情况下,多个核分配到的子任务稍短且时间消耗较为一致,此时使用并行计算是具有意义的;
·对于频繁读写内存的算法,开启并行计算并不是一个好的方案因为数据同步的时间消耗远超过计算的时间,此时并行的效率并不高,相反,如果一个算法较多的时间消耗在计算上而不是读写数据上,则使用并行计算会有较大的提升;
下面通过一个简单的例子说明如何把for循环改装为parfor循环:
Code #1-1
1.tic
2.n = 200;
3.A = 500;
4.a = zeros(n);
5.for i = 1:n
6.a(i) = max(abs(eig(rand(A))));
7.end
8.toc
如代码片1-1所示,该实例通过计算一个随机矩阵A的算法并把结果赋值到数组a中存储,循环内容之间计算是相互独立的,附加一个matlab的tic-toc语句来测量整片代码的计算时间,结果如下图所示:
作者使用的是笔记本处理器型号为i5-7200u,有2个物理内核,没经过并行计算优化时,代码的计算时间消耗为25.69秒左右。下面为经过parfor并行处理的代码片#1-2:
Code #1-2
1.tic
2.ticBytes(gcp);
3.n = 200;
4.A = 500;
5.a = zeros(n);
6.parfor i = 1:n
7.a(i) = max(abs(eig(rand(A))));
8.end
9.tocBytes(gcp)
10.toc
输出的结果为:
从上图中可以看到,在双核并行处理的作用下,处理时间从26秒提高到了16.8秒,理想时间应该为没有使用并行计算时间的二分之一,但其中的延迟包含了核心之间的同步和读写数据的延迟。
下面举一个使用parfor时效率并不高的例子
以下的代码片#1-3为通过循环产生一段正弦波信号数据:
Code #1-3
1.tic
2.n = 1024;
3.A = zeros(n);
4.for i = 1:n
5.A(i,:) = (1:n) .* sin(i*2*pi/1024);
6.end
7.toc
改写为并行计算parfor:
Code #1-4
1.tic
2.ticBytes(gcp);
3.n = 1024;
4.A = zeros(n);
5.parfor (i = 1:n)
6.A(i,:) = (1:n) .* sin(i*2*pi/1024);
7.end
8.tocBytes(gcp)
9.toc
从结果观察可以发现,代码改写为并行后速度并没有提升,反而比单核计算时要慢得多,是因为该代码片的数据传输量较大,导致多核处理时无法展现出优势。