将以下代码存储为m文件,运行
i=1:100000;
j=1:100000;
Y=0;
for i=1:100000
for j=1:1:100000
Y=Y+i+j;
end
end
CPU占用情况为:只运行了一个matlab.exe
p=parpool(3);
i=1:100000;
j=1:100000;
Y=0;
parfor i=1:100000
for j=1:1:100000
Y=Y+i+j;
end
end
delete(p);
说明:最新几版的Matlab可以将并行处理的工具包 parallel pool自动打开,不需要再去格外开启,只需要将for改为parfor。
但是我们这里还是进行开启和关闭partool,将以上代码存储为m文件,运行
p=parpool(3);
i=1:100000;
j=1:100000;
Y=0;
parfor i=1:100000
for j=1:1:100000
Y=Y+i+j;
end
end
delete(p);
命令行会显示
>> test_parallel
Starting parallel pool (parpool) using the 'local' profile ... connected to 3 workers.
CPU占用情况为:
发现虽然开启了3个parpool,但是共有4个matlab.exe在运行。其中1个应该是主控的,它基本不干活,只负责分配,进行计算时他的cpu占用率只有1~2%,其他3个进程是专门用来计算的。
若在代码开头不开启partool,只将for改为parfor,则CPU占用情况为:
发现开启了5个进程,其中4个进程占用情况类似。推测如果不用parfor可能matlab自身的负载均衡能够更好地利用CPU(?)。若服务器有12个core,比较暴力的做法是开3个matlab,将循环分成3部分,给每个matlab分配4个core(>>matlabpool local 4),每个程序里有一个parfor i = 1:4. 这样就可以用12个核。
我的电脑是4核8线程
若将开头代码改为
p=parpool(7);
则会出现报错:
>> test_parallel
Starting parallel pool (parpool) using the 'local' profile ... 错误使用 parpool (line 103)
You requested a minimum of 7 workers, but the cluster "local" has the NumWorkers property set to
allow a maximum of 4 workers. To run a communicating job on more workers than this (up to a
maximum of 512 for the Local cluster), increase the value of the NumWorkers property for the
cluster. The default value of NumWorkers for a Local cluster is the number of cores on the local
machine.
出错 test_parallel (line 1)
parpool(7);
若改为
p=parpool(5);
也不行
改为
p=parpool(4);
可以运行,这时开启了5个进程:
说明四核八线程的电脑只能申4个(而非8个)matlab local pool。
在以前版本的matlab中,开启多线程池用的命令是matlabpool,例如:
matlabpool('open',8);
这一步是想开启8线程的线程池,但是从R2013b(具体版本不是很确定)开始,parpool命令取代了matlabpool命令。
在以前版本的matlab中,若运行:
matlabpool local 4;
%parallel program
matlabpool close
其中4是core数目,如果是四核八线程的电脑,那么只能申4个(而非8个)matlab local pool。
说明:开启并行计算的前提是,每一次循环不依赖上一次循环的结果。
下列代码是不可取的:
parfor i = 3:10
f(i) = f(i-1)+f(i-2);
end
当只需要简单计算的多次循环迭代时,例如蒙特卡洛(Monte Carlo)模拟,parfor很有用。它将循环迭代分组,每个worker执行迭代的一部分。当迭代耗时很长的时候parfor也是有用的,因为许多worker可以同时执行迭代。
若计算量较小较简单,则不推荐使用parfor。因为parfor内有通信消耗,使用parfor可能不会使得通信时间缩短。
parfor循环中不能使用迭代或者关联性的赋值语句,因为多个核计算时无法交换数据。
parfor循环要求:
循环体的限制:
一个程序并行时要共享内存,而eval语句可能使程序进入错误的workspace,因此不要用eval,改用不同index赋值。
matlabpool local 2;
c = 1:5;
parfor i = 1:length(c)
a(i) = c(i);
end
对于双重循环,由于不能写两个parfor,有两种解决方案:
parfor i = 1:100000
parfor j = 1:100000
y(i,j) = i+j;
end
end
会报错,可以修改为:
i = 1:100000;
j = 1:100000;
[I,J] = meshgrid(i,j);
parfor i = 1:numel(I)
Y(i) = I(i)+J(i);
end
y = reshape(Y,length(i),length(j));
使用parfor时需要注意注意全局变量和局部变量。parfor里允许无限次引用之前就定义好的全局变量,但只允许写入之前使用过的单一变量,这个变量一般是会切片式的在parfor里被引用(i.e., parfor ii= 1:N; foo(ii, :)= XXXX; end) ,一般它的作用是输出数据。局部变量是指在parfor循环里引入的新变量,局部变量在parfor结束后会被直接销毁。当然,你可以在parfor内使用xlswrite之类的生成N个EXCEL表或者txt保存这些变量。
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删