分享

Matlab并行计算(新手)

 Tall_Tree 2023-03-12 发布于河北

1 Matlab不会自动开启多核并行

将以下代码存储为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
在这里插入图片描述

2 Matlab并行过程——parpool

  1. Request a number of workers;
p=parpool(3);
  1. Issue the normal command to run the program. The client program will call on the workers as needed;
i=1:100000;
j=1:100000;
Y=0;
parfor i=1:100000
    for j=1:1:100000
        Y=Y+i+j;
    end    
end
  1. Release the workers;
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个核。

3 电脑核数与parpool的关系

我的电脑是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

4 说明——matlabpool与partool

在以前版本的matlab中,开启多线程池用的命令是matlabpool,例如:

matlabpool('open',8);

这一步是想开启8线程的线程池,但是从R2013b(具体版本不是很确定)开始,parpool命令取代了matlabpool命令

在以前版本的matlab中,若运行:

matlabpool local 4;  
    %parallel program  
matlabpool close  

其中4是core数目,如果是四核八线程的电脑,那么只能申4个(而非8个)matlab local pool

5 并行实现——parfor或SPMD

说明:开启并行计算的前提是,每一次循环不依赖上一次循环的结果。

下列代码是不可取的:

parfor i = 3:10
       f(i) = f(i-1)+f(i-2);
end

5.1 parfor(parallel for)

当只需要简单计算的多次循环迭代时,例如蒙特卡洛(Monte Carlo)模拟,parfor很有用。它将循环迭代分组,每个worker执行迭代的一部分。当迭代耗时很长的时候parfor也是有用的,因为许多worker可以同时执行迭代。

若计算量较小较简单,则不推荐使用parfor。因为parfor内有通信消耗,使用parfor可能不会使得通信时间缩短。

parfor循环中不能使用迭代或者关联性的赋值语句,因为多个核计算时无法交换数据。

parfor循环要求:

  1. 任务间必须独立
  2. 循环间次序独立

循环体的限制:

  1. 不能引入变量(eg.eval,load,global,etc.)
  2. 不能含有break或return声明
  3. 不能嵌套另外的parfor循环

一个程序并行时要共享内存,而eval语句可能使程序进入错误的workspace,因此不要用eval,改用不同index赋值。

matlabpool local 2;  
c = 1:5;  
parfor i = 1:length(c)  
    a(i) = c(i);  
end

对于双重循环,由于不能写两个parfor,有两种解决方案:

  1. 将其中一个for改成parfor
  2. 利用meshgrid将双循环代码改为单循环,例如:
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));

以下内容为转载:

https://www.zhihu.com/question/343442170/answer/807474747

使用parfor时需要注意注意全局变量和局部变量。parfor里允许无限次引用之前就定义好的全局变量,但只允许写入之前使用过的单一变量,这个变量一般是会切片式的在parfor里被引用(i.e., parfor ii= 1:N; foo(ii, :)= XXXX; end) ,一般它的作用是输出数据。局部变量是指在parfor循环里引入的新变量,局部变量在parfor结束后会被直接销毁。当然,你可以在parfor内使用xlswrite之类的生成N个EXCEL表或者txt保存这些变量。

5.2 SPMD(Single Program/Multiple Data)

本节内容为转载:

https://blog.csdn.net/abcjennifer/article/details/17610705?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param

https://blog.csdn.net/xgx198831/article/details/41104291/

https://blog.csdn.net/awakeljw/article/details/72824674

单程序多任务进行任务并行

spmd
    statements
end

若有很多数据集,smpd将每个数据集在不同的worker上运行以此来实现并行。spmd中的一个重要的参数是labindex,它是指每个worker的索引,用来表示此时正在工作的是哪一个worker。

Spmd中的“Single program”方面指的是同一段代码运行在不同的多个lab上。你在一个Matlab客户端上运行一个程序,被标志为spmd模块的其他部分运行在其他lab上。当这些块运行完毕后,你的程序继续在客户端运行。 “Multiple data”方面指的是虽然spmd语句在所有的lab上运行相同的代码,但每一个lab可以有不同的,独有的数据。所以多数据集可以在多个lab上同时被容纳。一下是我总结的SPMD使用的两个场景:

The “single program” aspect of spmd means that the identical code runs on multiple labs. 就是说同一段程序应用于不同的样本(数据),所以一般针对随机抽样的并行,如

%% SPMD  
%example 1  
spmd   
A = rand(3,2); %generate a matrix A for each lab(worker)  
end  
for i = 1:length(A)  
    figure; imagesc(A{i});   
end  
  
%example 2  
a = 3;  
b = 4;  
spmd  
    c = labindex();  
    d = c+a;  
end  
c{2} = 5;  
spmd  
    f = c*b;  
end  
for i = 1:length(f)  
    fprintf('%d\t',f{i});%access the value of each lab  
end  

另外,SPMD也可以用于可替代parfor的块并行,在不同lab(worker)上对相同或不同的数据执行不同的并行操作,说起来有些拗口,具体看一下例子就明白了,下面我写的example3,4分别针对在不同lab上对相同数据和不同数据执行不同操作,它们都可以用parfor代替。

%example3 - deal with same Data by different parameters  
%add different values to same array Data  
Data = 1:100;  
spmd  
    switch labindex  
        case 1  
            Data = Data+1;  
        case 2  
            Data = Data+2;  
    end  
end  
% print Data{1} & Data{2} for checking  
              
%example4   
%add different values for different parts of array Data  
% [1:50]+1  
% [51:100]+2  
spmd  
    if labindex == 1  
        Data(1:50) = Data(1:50)+1;  
    else  
        Data(51:100) = Data(51:100)+2;  
    end  
end  

5.3 SPMD 与 parfor

本节内容为转载加自己翻译:

https:///questions/12385534/spmd-vs-parfor

 dataset_array={dataset1, dataset2}
 matlabpool open 2
 spmd
      my_function(dataset(labindex));
 end

 dataset_array={dataset1, dataset2}
 matlabpool open 2
 parfor i:1=2
      my_function(dataset(i));
 end

的区别:

spmd is a parallel region, while parfor is a parallel for loop. The difference is that in spmd region you have a much larger flexibility when it comes to the tasks you can perform in parallel. You can write a for loop, you can operate on distributed arrays and vectors. You can program an entire work flow, which in general consists of more than loops. This comes at a price: you need to know more about distributing the work and the data among your threads. Parallelizing the loop for example requires explicitly dividing the loop index ranges amongst the workers (which you did in your code by using labindex), and maybe creating distributed arrays.

parfor on the other hand only does this - a parallelized for loop. Automatically parallelized, you can add, so the work is divided between the workers by MATLAB.

If you only want to run a single loop in parallel and later work on the result on your local client, you should use parfor. If you want to parallelize your entire MATLAB program, you will have to deal with the complexities of spmd and work distribution.

翻译:

spmd是并行区域,而parfor是并行for循环。区别在于,在spmd区域中,您可以并行执行的任务具有更大的灵活性。您可以编写一个for循环,可以对分布式数组和向量进行操作。您可以对整个工作流程进行编程,该工作流程通常包含多个循环。这是有代价的:您需要更多地了解如何在线程之间分配工作和数据。例如,并行化循环需要在工作线程之间明确地划分循环索引范围(通过使用labindex在代码中进行此操作),并可能创建分布式数组。

另一方面,parfor做并行化的for循环。您可以添加自动并行化的工作,因此work可以通过MATLAB在workers之间进行划分。

如果只想并行运行一个循环,然后再在本地客户端上处理结果,则应使用parfor。如果要并行化整个MATLAB程序,则必须处理spmd和工作分配的复杂性。

注意:parfor,spmd不可以相互或者自身嵌套。

5.4 Composite类型

spmd中每个lab返回值以composite存储,如上面[code]example 1中的f就是以composite的形式展现。f{i}为第i个lab的返回值。最开始我们也可以创建Composite对象并进行初始化赋值。

f = Composite(2);

6 MATLAB并行计算其他工具说明

此外,matlab的大多数工具箱都开始支持并行计算,所以如果该问题可以用自带工具箱解决的可以使用工具箱自带的并行计算方法。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7 参考

转载自:

https://blog.csdn.net/xgx198831/article/details/41104291/

  1. MATLAB官网——Parallel Computing Toolbox
  2. 详细讲解并行用法
  3. 详细并行代码
  4. 多核计算平台中MATLAB_并行计算工具包
  5. Parallel Computing Toolbox User’s Guide

一些可参考的博文:

Matlab多核并行计算例子
https://blog.csdn.net/qq_38290475/article/details/82223148

Matlab并行计算较为专业的介绍
https://blog.csdn.net/enjoyyl/article/details/41929033

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多