之间做出选择spmd
,parfor
,parfeval
并行通信代码
运行并行计算,可以使用parfor
,parfeval
,parfevalOnAll
,或spmd
。每个构建依赖于不同的并行编程的概念。如果您需要在计算工人沟通,使用parfeval
,parfevalOnAll
,或spmd
。
使用
parfeval
或parfevalOnAll
如果您的代码可以分为一组任务,每个任务可以依赖于其他任务的输出。使用
spmd
如果您需要在计算工人之间的沟通。
计算与parfeval
是最好的表示为图,类似于看板与阻塞。一般来说,结果是来自工人计算完成后。你可以收集的执行结果parfeval
操作使用afterEach
或毕竟
。你通常使用的结果进一步计算。
计算与spmd
最好由流程图表示,类似于瀑布工作流。池工人执行spmd
语句称为实验室。实验室收集的结果可以在计算。有时,实验室必须与其他实验室交流才能完成他们的计算。
如果你不确定,问自己以下:在我沟通并行代码,每个计算可以完成员工之间没有任何沟通?如果是的,使用parfeval
。否则,使用spmd
。
同步和异步的工作
在选择parfor
,parfeval
,spmd
计算,考虑是否需要与客户同步。
parfor
和spmd
需要同步,因此阻止你在MATLAB上运行任何新的计算®客户端。parfeval
不需要同步,所以客户端是免费去追求其他工作。
多线程和比较性能ProcessPool
在本例中,您比较速度运行在客户端和一个函数ProcessPool
。一些MATLAB函数使用多线程。使用这些函数执行的任务在多个线程比单个线程。因此,如果使用这些功能的机器上有许多核心,本地集群可以执行比在客户端多线程。
支持函数万博1manbetxclientFasterThanPool
列出在本例中,返回真正的
如果在客户机上执行多个执行速度比parfor
循环。语法是一样的parfeval
:使用一个函数处理作为第一个参数,输出的数量作为第二个参数,然后给所有必需的参数的函数。
首先,创建一个本地ProcessPool
。
p = parpool (“本地”);
开始平行池(parpool)使用“本地”概要文件…连接到平行池(工人数量:6)。
检查的速度eig
函数运行使用clientFasterThanPool
万博1manbetx支持功能。创建一个匿名函数eig
代表你的函数调用。
[~,t_client t_pool] = clientFasterThanPool (@ (N) eig (randn (N)), 0, 500)
t_client = 22.6243
t_pool = 4.9334
平行池计算答案的速度比客户端。分t_client
通过maxNumCompThreads
找到每个线程的时间在客户端。
t_client / maxNumCompThreads
ans = 3.7707
工人在默认情况下都是单线程的。结果表明,每个线程的时间是相似的在客户端和游泳池,的价值t_pool
大约是1.5倍的价值t_client / maxNumCompThreads
。的eig
函数不受益于多线程。
接下来,检查速度陆
函数运行使用clientFasterThanPool
万博1manbetx支持功能。
[~,t_client t_pool] = clientFasterThanPool(@陆(N) (randn (N)), 0, 500)
t_client = 1.0225
t_pool = 0.4693
平行池通常计算答案的速度比客户端如果你的本地机器上有四个或更多的核心。分t_client
通过maxNumCompThreads
找到每个线程的时间。
t_client / maxNumCompThreads
ans = 0.1704
这个结果表明,每个线程的时间比池,更在客户机上的值t_pool
大概是3倍的价值t_client / maxNumCompThreads
。每个线程用于减少计算时间,表明陆
使用多线程。
定义辅助函数
支持函数万博1manbetxclientFasterThanPool
检查计算是否更快在客户机上比在一个平行的池。需要输入一个函数处理fcn
和数量可变的输入参数(三机一体,in2,…
)。clientFasterThanPool
执行fcn(三机一体、in2…)
在客户端和活跃的平行池。作为一个例子,如果你想测试兰特(500)
,你的函数处理必须在以下形式:
fcn = @ (N)兰德(N);
然后,用clientFasterThanPool (fcn, 500)
。
函数(因此,t_multi t_single) = clientFasterThanPool (fcn numout,变长度输入宗量)% Preallocate单元阵列的输出输出=细胞(numout);%客户抽搐为i = 1:200如果numout = = 0 fcn(变长度输入宗量{:});其他的{1:numout}[输出]= fcn(变长度输入宗量{:});结束结束t_multi = toc;%平行池vararginC = parallel.pool.Constant(变长度输入宗量);抽搐parfori = 1:200% Preallocate单元阵列的输出输出=细胞(numout);如果numout = = 0 fcn (vararginC.Value {:});其他的{1:numout}[输出]= fcn (vararginC.Value {:});结束结束t_single = toc;%如果multhreading更快,返回true结果= t_single > t_multi;结束
比较的性能parfor
,parfeval
,spmd
使用spmd
可以慢或快于使用parfor
循环或parfeval
,这取决于类型的计算。影响的相对性能开销parfor
循环,parfeval
,spmd
。
对于一组任务,parfor
和parfeval
通常执行比spmd
在这种情况下。
计算每个任务的时间是不确定的。
每个任务计算时间不统一。
返回的数据从每个任务很小。
使用parfeval
当:
你想在后台运行计算。
每个任务依赖于其他任务。
在本例中,您可以执行检查矩阵运算的速度在使用parfor
循环,parfeval
,spmd
。
首先,创建一个本地平行池p
。
p = parpool (“本地”);
开始平行池(parpool)使用“本地”概要文件…连接到平行池(工人数量:6)。
计算随机矩阵
检查随机矩阵的速度可以通过使用生成parfor
循环,parfeval
,spmd
。试验的数量(n
)和的矩阵大小(米
——- - - - - -米
矩阵)。增加试验的数量提高后分析中使用的统计数据,但不影响计算本身。
m =1000年;n =20.;
然后,使用一个parfor
循环执行兰特(米)
一旦为每个工人。时间的每一个n
试用
parforTime = 0 (n, 1);为我= 1:n抽搐;垫=细胞(1、p.NumWorkers);parforN = 1: p。NumWorkers垫{N} =兰德(m);结束parforTime (i) = toc;结束
下一步,使用parfeval
执行兰特(米)
一旦为每个工人。时间的每一个n
试用
parfevalTime = 0 (n, 1);为我= 1:n抽搐;f (1: p.NumWorkers) = parallel.FevalFuture;为N = 1: p。NumWorkers f (N) = parfeval (@rand 1 m);结束垫= fetchOutputs (f,“UniformOutput”、假)”;parfevalTime (i) = toc;清晰的f结束
最后,使用spmd
执行兰特(米)
曾经为细节为每个实验室。实验室,如何执行命令spmd
,请参阅运行单一程序在多个数据集。时间的每一个n
试用
spmdTime = 0 (n, 1);为我= 1:n抽搐;spmde =兰德(m);结束特征值= {e {:}};spmdTime (i) = toc;结束
使用rmoutliers
去除离群值的每一个试验。然后,用箱线图
比较次。
%躲离群值boxData = rmoutliers ([parforTime parfevalTime spmdTime]);%绘制数据箱线图(boxData“标签”,{“parfor”,“parfeval”,“spmd”},“象征”,”)ylabel (的时间(秒))标题(“n随机矩阵(m m)的)
通常情况下,spmd
每评价比需要更多的开销parfor
或parfeval
。因此,在这种情况下,使用parfor
循环或parfeval
是更有效的。
计算和随机矩阵
其次,计算随机矩阵的总和。你可以通过使用一个变量与减少parfor
循环,计算后求和parfeval
,或gplus
与spmd
。再次,设定试验的数量(n
)和的矩阵大小(米
——- - - - - -米
矩阵)。
m =1000年;n =20.;
然后,使用一个parfor
循环执行兰特(米)
一旦为每个工人。计算和减少变量之和。时间的每一个n
试用
parforTime = 0 (n, 1);为我= 1:n抽搐;结果= 0;parforN = 1: p。NumWorkers结果=结果+兰德(m);结束parforTime (i) = toc;结束
下一步,使用parfeval
执行兰特(米)
一旦为每个工人。使用fetchOutputs
在所有的矩阵,然后使用总和
。时间的每一个n
试用
parfevalTime = 0 (n, 1);为我= 1:n抽搐;f (1: p.NumWorkers) = parallel.FevalFuture;为N = 1: p。NumWorkers f (N) = parfeval (@rand 1 m);结束结果=总和(fetchOutputs (f));parfevalTime (i) = toc;清晰的f结束
最后,使用spmd
执行兰特(米)
每个实验室。使用一次gplus
和所有的矩阵。发送结果只有第一个实验室,设置可选的targetlab
参数1
。时间的每一个n
试用
spmdTime = 0 (n, 1);为我= 1:n抽搐;spmdr = gplus(兰德(m), 1)公关;结束结果= r {1};spmdTime (i) = toc;结束
使用rmoutliers
去除离群值的每一个试验。然后,用箱线图
比较次。
%躲离群值boxData = rmoutliers ([parforTime parfevalTime spmdTime]);%绘制数据箱线图(boxData“标签”,{“parfor”,“parfeval”,“spmd”},“象征”,”)ylabel (的时间(秒))标题(的n和随机矩阵(m m)的)
对于这个计算,spmd
明显的速度比吗parfor
循环或parfeval
。当你使用在减少变量parfor
循环,你广播的每一次迭代的结果parfor
循环的所有工人。相比之下,spmd
调用gplus
只有一次做一个全球减少操作,需要更少的开销。因此,开销减少计算的一部分
为spmd
,
为parfor
。