主要内容

之间做出选择spmd,parfor,parfeval

并行通信代码

运行并行计算,可以使用parfor,parfeval,parfevalOnAll,或spmd。每个构建依赖于不同的并行编程的概念。如果您需要在计算工人沟通,使用parfeval,parfevalOnAll,或spmd

  • 使用parfevalparfevalOnAll如果您的代码可以分为一组任务,每个任务可以依赖于其他任务的输出。

  • 使用spmd如果您需要在计算工人之间的沟通。

计算与parfeval是最好的表示为图,类似于看板与阻塞。一般来说,结果是来自工人计算完成后。你可以收集的执行结果parfeval操作使用afterEach毕竟。你通常使用的结果进一步计算。

计算与spmd最好由流程图表示,类似于瀑布工作流。池工人执行spmd语句称为实验室。实验室收集的结果可以在计算。有时,实验室必须与其他实验室交流才能完成他们的计算。

如果你不确定,问自己以下:在我沟通并行代码,每个计算可以完成员工之间没有任何沟通?如果是的,使用parfeval。否则,使用spmd

同步和异步的工作

在选择parfor,parfeval,spmd计算,考虑是否需要与客户同步。

parforspmd需要同步,因此阻止你在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

对于一组任务,parforparfeval通常执行比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每评价比需要更多的开销parforparfeval。因此,在这种情况下,使用parfor循环或parfeval是更有效的。

计算和随机矩阵

其次,计算随机矩阵的总和。你可以通过使用一个变量与减少parfor循环,计算后求和parfeval,或gplusspmd。再次,设定试验的数量(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只有一次做一个全球减少操作,需要更少的开销。因此,开销减少计算的一部分 O ( n 2 ) spmd, O ( n 2 ) parfor

另请参阅

||

相关的话题