主要内容

parfeval

在并行池工作线程上异步执行函数

描述

例子

F= parfeval (pfcnnumout三机一体,in2,…请求函数的异步执行fcn并行池中包含的工作线程p,希望numout输出参数和作为输入参数提供三机一体,in2,….的异步计算fcn不会阻塞MATLAB。F是一个平行的。FevalFuture对象,当工作者完成计算时,可以从中获得结果fcn.评价fcn总是继续,除非通过调用显式地取消执行取消(F).若要请求多个函数求值,必须调用parfeval很多次了。(然而,parfevalOnAll可以在所有worker上运行相同的函数。)

例子

F= parfeval (fcnnumout三机一体,in2,…请求在当前并行池上异步执行。如果不存在池,它将启动一个新的并行池,除非并行首选项禁用自动创建池。

例子

全部折叠

当你使用parfevalparfevalOnAll要在后台运行计算,需要创建名为期货的对象。您可以使用状态属性,以查明它是正在运行、排队还是已完成。你也可以使用FevalQueue属性,以访问正在运行和排队的期货。要取消期货,您可以使用取消函数。在这个例子中,你:

  • 使用取消直接取消期货。

  • 检查已完成期货的完成错误。

  • 使用FevalQueue物业进入期货。

向队列添加工作

创建一个并行池p有两个工人。

P = parpool(2);
使用“本地”配置文件启动并行池(parpool)…连接到并行池(工人数:2)。

当你使用parfeval为了在后台运行计算,该函数为每个计算创建一个future,并将其添加到池队列中。任务一直在队列中,直到一个worker空闲。当一个worker空闲时,如果队列不为空,它就开始计算一个任务。当一个worker完成一个任务时,该任务将从队列中移除,该worker变为空闲。

使用parfeval创建一个期货数组f通过指示工作人员执行函数暂停.使用的论证1对于第三个未来,和一个争论所有其他的未来。

N = 1:5如果N == 3 f(N) = parfeval(@pause,0,1);其他的f(n) = parfeval(@pause,0,Inf);结束结束

每次使用parfeval返回一个表示函数在worker上执行的future对象。除了第三个未来,每一个未来都需要无限多的时间来计算。未来是由parfeval (@pause 0正)是未来的一个极端情况,它会降低队列的速度。

直接取消期货

您可以使用状态财产获得期货地位。构造一个单元数组的每个未来的状态f

{f。州}
ans =1×5单元{“奔跑”}{“奔跑”}{“排队”}{“排队”}{“排队”}

除了第三个任务,其他任务都永远暂停。

取消第二个将来直接用取消

取消(f (2));{f。州}
ans =1×5单元{“奔跑”}{'完成'}{“奔跑”}{“排队”}{“排队”}

在你取消第二个将来时后,第三个将来时运行。等待第三个未来完成,然后再次检查状态。

等待(f (3));{f。州}
ans =1×5单元{“奔跑”}{'完成'}{'完成'}{“奔跑”}{“排队”}

第三个未来现在有了国家“完成”

检查完成错误

当一个未来完成时,它就完了状态房地产成为“完成”.要区分被取消的期货和正常完成的期货,请使用错误财产。

流(“f (2): % s \ n”f (2) .Error.message)
f(2):期货被取消执行。
流(“f (3): % s \ n”f (3) .Error.message)
f (3):

如message属性所示,代码取消了第二个未来。第二个将来时被取消了,正如在消息财产。第三个future完成时没有出现错误,因此没有错误消息。

取消池队列中的期货

您可以使用FevalQueue属性访问池队列中的期货。

p.FevalQueue
ans = FevalQueue with properties: Number Queued: 1 Number Running: 2

队列有两个属性:RunningFutures而且QueuedFutures.的RunningFutures属性是与当前正在运行的任务相对应的期货数组。

disp (p.FevalQueue.RunningFutures)
1 x2 FevalFuture数组:ID状态FinishDateTime功能错误  -------------------------------------------------------- 1 12运行@pause 2 15 @pause运行

QueuedFutures属性是与当前排队且未运行的任务对应的期货数组。

disp (p.FevalQueue.QueuedFutures)
FevalFuture with properties: ID: 16函数:@pause CreateDateTime: 15-Jul-2020 17:29:37 StartDateTime:运行时间:0天0h 0m 0s状态:排队错误:无

您可以取消单个期货或一组期货。取消所有的期货QueuedFutures

取消(p.FevalQueue.QueuedFutures);{f。州}
ans =1×5单元{“奔跑”}{'完成'}{'完成'}{“奔跑”}{'完成'}

RunningFutures而且QueuedFutures从最新到最旧,不管是否f是按从最新到最老的顺序排列的。每个未来都是独一无二的ID属性。检查ID每个期货的属性f

disp (f)
1x5 FevalFuture array: ID State FinishDateTime Function Error -------------------------------------------------------------- 1 12 running @pause 2 13 finished (unread) 15- july -2020 17:29:37 @pause Error 3 14 finished (unread) 15- july -2020 17:29:39 @pause 4 15 running @pause 5 16 finished (unread) 15- july -2020 17:29:39 @pause Error

将结果与ID的属性RunningFutures

j = 1:length(p.FevalQueue.RunningFutures) rf = p.FevalQueue.RunningFutures(j);流("p.FevalQueue.RunningFutures(%i): ID = %i\n", j, rf.ID)结束
p.FevalQueue.RunningFutures(1): ID = 12 p.FevalQueue.RunningFutures(2): ID = 15

在这里,RunningFutures是一个数组,包含f (1)而且f (4).如果你取消RunningFutures (2),你取消了第四个未来f (4)

有时,未来在工作空间中不可用,例如,如果您在同一段代码完成之前执行了两次,或者如果您使用parfeval在函数中。您可以取消工作区中不可用的期货。

清晰的f从工作空间。

清晰的f

你可以使用RunningFutures而且QueuedFutures进入尚未完成的期货。使用RunningFutures取消f (4)

rf2 = p.FevalQueue.RunningFutures(2);取消(rf2) rf2。状态
Ans = 'finished'

要取消队列中的所有期货,请使用以下代码。

取消([p.FevalQueue。RunningFuturesp.FevalQueue.QueuedFutures])

使用parfeval请求在工作线程上异步执行函数。

例如,向并行池提交单个请求。通过使用检索输出fetchOutputs

F = parfeval(@magic,1,10);value = fetchOutputs(f);

类型中提交多个未来请求的向量-循环并收集可用的结果。为了提高效率,请预先分配一个未来对象数组。

f(1:10) = parallel.FevalFuture;Idx = 1:10 f(Idx) = parfeval(@magic,1, Idx);结束

通过使用检索单个未来输出fetchNext

magicResults = cell(1,10);idx = 1:10 [completedIdx,value] = fetchNext(f);magicResults{completedIdx} = value;流('得到索引为%d.\n的结果', completedIdx);结束

此示例演示如何执行与的并行参数扫描parfeval并在计算过程中返回结果DataQueue对象。parfeval不会阻塞MATLAB,所以你可以在计算发生时继续工作。

本例对常微分方程的Lorenz系统进行了参数扫描 σ 而且 ρ ,显示了这个系统的混沌本质。

d d t x σ y - z d d t y x ρ - z - y d d t z xy - β x

创建参数网格

定义要在参数扫描中查看的参数范围。

gridSize = 40;sigma = linspace(5, 45, gridSize);rho = linspace(50,100, gridSize);Beta = 8/3;

控件创建参数的2-D网格meshgrid函数。

[rho,sigma] = meshgrid(rho,sigma);

创建一个图形对象,并设置“可见”真正的这样它就会在活动脚本之外的一个新窗口中打开。要可视化参数扫描的结果,请创建一个曲面图。注意,初始化Z表面的分量创建一个空情节。

图(“可见”,真正的);surface = surf(rho,sigma,NaN(size(sigma)));包含(‘\ρ“翻译”“泰克斯”) ylabel (‘\σ’“翻译”“泰克斯”

设置并行环境

方法创建并行工作池parpool函数。

parpool;
使用“本地”配置文件启动并行池(parpool)…连接到并行池(工人数:6)。

要从工作线程发送数据,可以创建DataQueue对象。方法设置一个函数,该函数在工作人员每次发送数据时更新曲面图afterEach函数。的updatePlotFunction是在示例末尾金宝app定义的支持函数。

Q = parallel.pool.DataQueue;afterEach (Q, @(数据)updatePlot(表面、数据));

执行并行参数扫描

定义了参数之后,就可以执行并行参数扫描了。

parfeval当你分配工作负载时,工作效率更高。要分配工作负载,请将要查看的参数分组到分区中。对于本例,将其划分为大小一致的分区一步通过使用冒号操作符().生成的数组分区包含分区的边界。注意,必须添加最后一个分区的端点。

Step = 100;分区=[1:步骤:数字(西格玛),数字(西格玛)+1]
分区=1×171101 201 301 401 501 601 701 801 901 1001 1101 1201 1301 1401 1501 1601

为了获得最佳性能,请尝试将其划分为以下分区:

  • 与调度分区的开销相比,足够大的计算时间。

  • 足够小,以至于有足够的分区来让所有的工作人员忙碌。

要表示并行工作线程上的函数执行并保存其结果,请使用future对象。

f(1:numel(partitions)-1) = parallel.FevalFuture;

方法将计算卸载给并行工作者parfeval函数。parameterSweep是这个脚本末尾定义的一个辅助函数,它在要探索的参数分区上求解Lorenz系统。它有一个输出参数,所以必须指定1作为输出的数量parfeval

ii = 1:数值(分区)-1 f(ii) = parfeval(@parameterSweep,1,分区(ii),分区(ii+1),西格玛,rho,beta,Q);结束

parfeval不会阻塞MATLAB,所以你可以在计算发生时继续工作。工作人员并行计算,并将中间结果通过DataQueue一旦有了它们。

如果你想阻止MATLAB直到parfeval完成后,使用等待函数在未来对象上。使用等待函数在后续代码依赖于的完成时非常有用parfeval

等待(f);

parfeval完成计算,等待完成后,您可以执行更多的代码。例如,绘制结果曲面的等高线。使用fetchOutputs函数检索存储在未来对象中的结果。

results =重塑(fetchOutputs(f),gridSize,[]);contourf(ρ,σ,结果)包含(‘\ρ“翻译”“泰克斯”) ylabel (‘\σ’“翻译”“泰克斯”

如果参数扫描需要更多的计算资源,并且您可以访问集群,则可以扩展您的parfeval计算。有关更多信息,请参见从桌面扩展到集群

定义Helper函数

定义一个辅助函数,在要探索的参数分区上求解Lorenz系统。将中间结果发送到MATLAB客户端发送函数在DataQueue对象。

函数results = parameterscan (first,last,sigma,rho,beta,Q) results = 0 (last-first,1);2 =第一:持续1 lorenzSystem = @ (t))(σ(ii) * ((2) - (1));A (1)*(rho(ii) - A (3)) - A (2);A (1)* A (2) - * A (3)];[t,a] = ode45(lorenzSystem,[0 100],[1 1 1]);Result = a(end,3);发送(Q, [ii,结果]);Results (ii-first+1) = result;结束结束

定义另一个辅助函数,在新数据到达时更新曲面图。

函数updatePlot(surface,data) surface. zdata (data(1)) = data(2);drawnow (“limitrate”);结束

这个例子展示了如何在计算完成时更新用户界面。当您将计算卸载给使用parfeval,当工作人员执行这些计算时,所有用户界面都是响应式的。在本例中,使用waitbar创建一个简单的用户界面。

  • 使用afterEach在每次计算完成后更新用户界面。

  • 使用毕竟在所有计算完成后更新用户界面。

使用waitbar要创建一个数字句柄,h.当你使用afterEach毕竟,waitbar函数更新图形句柄。有关句柄对象的详细信息,请参见处理对象行为

H = waitbar(0,“等……”);

使用parfeval计算随机矩阵特征值的实部。使用默认首选项,parfeval如果尚未创建并行池,则自动创建并行池。

idx = 1:10 0 f (idx) = parfeval (@ (n)真实(eig (randn (n))), 1、5 e2);结束

你可以使用afterEach的每个结果上自动调用函数parfeval计算。使用afterEach在每个future完成后,计算每个输出数组中的最大值。

maxFuture = afterEach(f,@max,1);

您可以使用状态财产获得期货地位。创建一个逻辑数组,其中状态期货的性质f“完成”.使用的意思是计算成品期货的比例。然后,创建一个匿名函数updateWaitbar.该函数改变的分数等待条的长度h到成品期货的比例。

updateWaitbar = @(~) waitbar(mean({f.)州}= =“完成”), h);

使用afterEach而且updateWaitbar在每个future in之后更新分数等待条长度maxFuture完成。使用毕竟而且删除在所有计算完成后关闭等待栏。

updateWaitbarFutures = afterEach(f,updateWaitbar,0);毕竟(updateWaitbarFutures @(~)删除(h), 0);

使用毕竟而且柱状图中显示结果的直方图maxFuture在所有的期货完成之后。

showsHistogramFuture = afterAll(maxFuture,@直方图,0);

输入参数

全部折叠

并行工人池,指定为a平行的。池对象。方法创建并行池parpool函数。

数据类型:平行的。池

函数要在工作者上执行,指定为函数句柄。

例子:FCN = @sum

数据类型:function_handle

所期望的输出参数的个数fcn

数据类型:||int8|int16|int32|int64|uint8|uint16|uint32|uint64

要传递给的函数参数fcn,指定为逗号分隔的变量或表达式列表。

输出参数

全部折叠

对象,返回为平行的。FevalFuture,表示的执行fcn并保存其结果。使用fetchOutputsfetchNext收集结果。

在R2013b中引入