主要内容

parallel.pool.DataQueue

发送和侦听客户机和工人之间的数据

    描述

    一个DataQueue使异步发送数据或消息从工人回客户机在一个平行的池进行了计算。例如,您可以得到中间值和计算的进展的迹象。

    从并行发送数据池的工人回客户机,首先构造一个DataQueue在客户端。通过这个DataQueue成一个parfor循环或其他并行语言构造,如spmd。工人的电话发送将数据发送回客户机。在客户端,注册一个函数被称为每次收到数据使用afterEach

    • 你可以叫发送从创建的员工或客户DataQueue(如果需要的话)。

    • 你可以在工人们建造队列并将其发送回客户端,使沟通在相反的方向。然而,你不能发送队列从一名工人到另一个。工人之间传输数据,使用spmd,spmdSend,或spmdReceive代替。

    • 与其他处理对象不同,DataQueuePollableDataQueue实例做保持联系当他们被发送到工人。

    创建

    描述

    例子

    = parallel.pool.DataQueue创建一个对象,可以用来发送或监听消息(或数据)从不同的工人。创建DataQueue在员工或客户你想接收的数据。

    属性

    全部展开

    这个属性是只读的。

    的数据项的数量等待从队列中删除指定为零或正整数。这个值是0或者一个正整数的员工或客户创建了PollableDataQueue实例。如果客户端创建PollableDataQueue例如,值0在所有的工人。如果一个工人创造了PollableDataQueue,价值0在客户端和其他工人。

    对象的功能

    afterEach 定义一个函数调用DataQueue当接收到新的数据
    发送 从工人到客户端发送数据使用一个数据队列

    例子

    全部折叠

    构造一个DataQueue,叫afterEach

    q = parallel.pool.DataQueue;afterEach (q, @disp);
    开始一个parfor循环,发送一条消息。等待消息被传递到afterEach函数,在这个例子中@disp

    parfor我= 1:3发送(问我);结束;
    1 2 3

    为更多的细节在监听数据使用DataQueue,请参阅afterEach

    当你发送一个消息DataQueue对象,消息队列中等待处理,直到一个侦听器。每个消息增加了1队列长度。在本例中,您使用QueueLength属性的长度DataQueue对象。

    当一个客户端或工人创建一个DataQueue对象,任何消息发送到队列在客户机或工人的记忆。如果客户端创建一个DataQueue对象,QueueLength属性在所有工人0。在本例中,您创建一个DataQueue对象在客户端,发送数据从一个工人。

    首先,创建一个平行池和一个工人。

    parpool (1);
    开始平行池(parpool)使用“本地”概要文件…连接到平行池(工人数量:1)。

    然后,创建一个DataQueue

    q = parallel.pool.DataQueue
    q = DataQueue属性:QueueLength: 0

    一个新创建的DataQueue有一个空的队列。您可以使用parfor找到q.QueueLength在工人。找到客户端的队列长度,队列长度的工人。

    流(“我在客户端:% \ n”q.QueueLength)
    在客户端:0
    parfori = 1流(“我在工人:% \ n”q.QueueLength)结束
    工人:0

    队列是空的,QueueLength0对于客户机和工人。接下来,从工人到队列发送一条消息。然后,使用QueueLength财产发现队列的长度。

    %先发送一条消息parfori = 1发送(q,“消息”);结束%的长度流(“我在客户端:% \ n”q.QueueLength)
    在客户端:1
    parfori = 1流(“我在工人:% \ n”q.QueueLength)结束
    工人:0

    QueueLength属性是1在客户端,0在工人。立即创建一个侦听器来处理队列的显示数据。

    el = afterEach (q, @disp);

    等到队列为空,然后删除侦听器。

    q.QueueLength> 0 pause(0.1);结束删除(el);

    使用QueueLength财产发现队列的长度。

    流(“我在客户端:% \ n”q.QueueLength)
    在客户端:0

    QueueLength0因为队列处理完成。

    在本例中,您使用一个DataQueue更新等酒吧的进展parfor循环。

    当您创建一个parfor每次迭代循环,你将工人在一个平行的池。当返回的信息仅仅是工人parfor循环完成。您可以使用一个DataQueue更新等酒吧在每个迭代。

    当你更新一个酒吧的进展等parfor循环,客户端必须记录信息进行了多少次迭代依然存在。

    提示

    如果你正在创造新的并行代码和想监控代码的进展,考虑使用parfeval工作流。有关更多信息,请参见使用afterEach和毕竟异步更新用户界面

    辅助函数parforWaitbar,在这个例子中,定义更新等待酒吧。这个函数使用持续的余下的迭代的数量来存储信息。

    使用waitbar创建一个酒吧等,w

    w = waitbar (0,“请等待…”);

    创建一个DataQueue,D。然后使用afterEach运行parforWaitbar消息被发送后DataQueue

    %创建DataQueue和侦听器D = parallel.pool.DataQueue;afterEach (D, @parforWaitbar);

    为你设定的迭代次数parfor循环,N。使用等栏w和迭代次数N初始化函数parforWaitbar

    在每个迭代结束时parfor循环中,客户端运行parforWaitbar和增量更新等酒吧。

    N = 100;parforWaitbar (w, N)

    这个函数parforWaitbar使用持久变量来存储在客户端完成的迭代的数量。从工人们不需要的信息。

    运行一个parfor循环与N迭代。对于这个示例,使用暂停兰德模拟一些工作。每一次迭代后,使用发送发送消息到一个DataQueue。当一个消息发送到目的地DataQueue酒吧,等待更新。因为工人不需要信息,发送空消息,以避免不必要的数据传输。

    parfor循环完成后,使用删除关闭酒吧等。

    parfori = 1: N暂停(rand)发送(D, []);结束删除(w);

    定义的helper函数parforWaitbar。当您运行parforWaitbar有两个输入参数,函数初始化三个持久变量(,h,N)。当您运行parforWaitbar一个输入参数,等待更新。

    函数parforWaitbar (waitbarHandle、迭代)持续的数h N如果输入参数个数= = 2%初始化数= 0;h = waitbarHandle;N =迭代;其他的%更新waitbar%检查手柄是否删除对象的引用如果isvalid (h)数=计数+ 1;waitbar(数/ N、h);结束结束结束

    这个例子展示了如何执行一个平行的参数扫描parfeval在计算,并发送结果DataQueue对象。

    parfeval不阻止MATLAB,所以你可以继续工作,而计算。

    示例执行参数扫描对洛伦兹系统的常微分方程,在参数 σ ρ ,显示该系统的混沌特性。

    d d t x = σ ( y - - - - - - z ) d d t y = x ( ρ - - - - - - z ) - - - - - - y d d t z = xy - - - - - - β x

    创建参数网格

    定义参数的范围,你想探索在参数扫描。

    gridSize = 40;σ= linspace (5 45 gridSize);gridSizeρ= linspace (100);β= 8/3;

    创建一个二维网格的参数使用meshgrid函数。

    (ρ,σ)= meshgrid(ρ,σ);

    创建一个图对象,并设置“可见”真正的在新窗口中打开,生活之外的脚本。可视化的结果参数扫描,创建一个曲面图。注意,初始化Z组件的表面创建一个空的阴谋。

    图(“可见”,真正的);表面=冲浪(ρ,σ,南(大小(σ)));包含(‘\ρ,“翻译”,“泰克斯”)ylabel (‘\σ’,“翻译”,“泰克斯”)

    设置并行环境

    创建一个池的平行工人使用parpool函数。

    parpool;
    开始平行池(parpool)使用过程的概要文件…连接到平行池(工人数量:6)。

    从工人发送数据,创建一个DataQueue对象。建立一个函数,每次更新曲面图一个工人发送数据使用afterEach函数。的updatePlot函数是一个支持函数定义的例子金宝app。

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

    并行执行参数扫描

    在定义参数之后,您可以执行并行扫描参数。

    parfeval工作更有效地分布工作负载。分发工作负载,集团探索到分区的参数。对于本例,分成均匀的分区大小一步通过使用冒号运算符(:)。由此产生的数组分区包含分区的边界。请注意,您必须添加最后一个分区的终点。

    一步= 100;分区=[1:步骤:元素个数(σ),元素个数(σ)+ 1]
    分区=1×171 101 201 301 401 501 601 701 801 901 1001 1101 1201 1301 1401 1501 1601

    为获得最佳性能,尝试分成的分区:

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

    • 足够小,有足够的分区让所有工人忙碌。

    代表函数执行并行工人和持有他们的结果,使用未来的对象。

    f(1:元素个数(分区)1)= parallel.FevalFuture;

    卸载计算并行工人使用parfeval函数。parameterSweep最后一个helper函数定义的脚本,解决了洛伦兹系统分区参数的探索。它有一个输出参数,所以你必须指定1输出的数量parfeval

    2 = 1:元素个数(分区)1 f (2) = parfeval (@parameterSweep 1(2)分区,分区(2 + 1),σ,ρ,β,Q);结束

    parfeval不阻止MATLAB,所以你可以继续工作,而计算。工人们,把中间结果通过并行计算DataQueue一旦他们成为可用。

    如果你想阻止MATLAB直到parfeval完成后,使用等待函数对未来对象。使用等待函数非常有用当后续代码取决于完成parfeval

    等待(f);

    parfeval完成计算,等待完成,你可以执行更多的代码。例如,绘制轮廓的表面。使用fetchOutputs函数来检索结果存储在未来的对象。

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

    如果你的参数扫描需要更多的计算资源,你可以访问一个集群,你可以扩大你的parfeval计算。有关更多信息,请参见从桌面到集群规模

    定义辅助函数

    定义一个helper函数,解决了洛伦兹系统分区参数的探索。将中间结果发送到客户机通过使用MATLAB发送功能上的DataQueue对象。

    函数结果= parameterSweep(首先,最后,σ,ρ,β,Q)结果= 0 (last-first, 1);2 =第一:持续1 lorenzSystem = @ (t))(σ(ii) * ((2) - (1));(1)*(ρ(2)- (3)),(2);(1)*(2)-β* (3)];[t] =数值(lorenzSystem, 100年[0],[1 1 1]);结果=(结束,3);发送(Q, [ii,结果]);结果(ii-first + 1) =结果;结束结束

    定义另一个helper函数,更新新的数据到达时曲面图。

    函数updatePlot(表面数据)surface.ZData(数据(1))=数据(2);drawnow (“limitrate”);结束

    版本历史

    介绍了R2017a