主要内容

parallel.pool.DataQueue

在客户机和工作人员之间发送和侦听数据

    描述

    A.数据队列在执行计算时,允许在并行池中将工作人员的数据或消息异步发送回客户端。例如,您可以获取中间值和计算进度指示。

    要将数据从并行池工作程序发送回客户端,首先构造数据队列在客户端中。传递这个数据队列成一个帕弗-循环或其他并行语言构造,例如spmd.工人们打电话来发送将数据发送回客户端。在客户端,使用之后

    • 你可以打电话发送从创建数据队列,如有需要。

    • 您可以在工作进程上构造队列并将其发送回客户端,以启用反向通信。但是,您不能将队列从一个工作进程发送到另一个工作进程。若要在工作进程之间传输数据,请使用spmd,拉布森德拉伯雷相反

    • 与所有其他句柄对象不同,数据队列可轮询数据队列实例在被发送给worker时仍然保持连接。

    创造

    描述

    实例

    Q=parallel.pool.DataQueue创建一个对象,该对象可用于发送或侦听来自不同工作人员的消息(或数据)。创建数据队列在您希望接收数据的工作人员或客户端上。

    性质

    全部展开

    此属性是只读的。

    等待从队列中删除的数据项数,指定为零或正整数。值为0或创建可轮询数据队列实例。如果客户端创建可轮询数据队列例如,该值为0在所有工人上。如果工人创建可轮询数据队列,值为0对客户和所有其他员工负责。

    目标函数

    之后 定义在DataQueue上接收到新数据时要调用的函数
    发送 使用数据队列将数据从工作者发送到客户端

    例子

    全部崩溃

    建造一个数据队列,并致电之后

    q = parallel.pool.DataQueue;afterEach (q, @disp);
    开始帕弗-loop,并发送消息。挂起的消息被传递给之后函数,在本例中@disp

    帕弗i=1:3发送(q,i);终止;
    1 2 3

    要了解更多关于使用数据队列看见之后

    当您将消息发送到数据队列对象,消息在队列中等待,直到侦听器对其进行处理1.在本例中,您使用队列长度属性来查找数据队列对象。

    当客户或工作人员创建数据队列对象时,发送到队列的任何消息都保存在该客户端或工作人员的内存中。如果客户端创建数据队列对象队列长度所有工人的财产都是合法的0。在本例中,您创建了一个数据队列对象,并从工作进程发送数据。

    首先,创建一个具有一个工作线程的并行池。

    帕尔普(1);
    正在使用连接到并行池的“本地”配置文件启动并行池(parpool)(工作进程数:1)。

    然后,创建一个数据队列

    q = parallel.pool.DataQueue
    q =具有属性的DataQueue: QueueLength: 0

    一个新创建的数据队列有一个空队列。您可以使用帕弗找到q.QueueLength在工人身上。查找客户机上的队列长度,以及工作机上的队列长度。

    fprintf('在客户端上:%i\n',q.队列长度)
    在客户端上:0
    帕弗i=1 fprintf('在工作进程上:%i\n',q.队列长度)终止
    在工作进程上:0

    由于队列为空,因此队列长度0对于客户端和工作进程。接下来,从工作进程向队列发送消息。然后,使用队列长度属性来查找队列的长度。

    %先发个短信帕弗i=1发送(q,“消息”);终止%找出长度fprintf('在客户端上:%i\n',q.队列长度)
    关于客户:1
    帕弗i=1 fprintf('在工作进程上:%i\n',q.队列长度)终止
    在工作进程上:0

    这个队列长度属性是1.在客户端,和0在工人。创建一个侦听器,通过立即显示数据来处理队列。

    el=每次之后(q,@disp);

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

    虽然q、 QueueLength>0暂停(0.1);终止删除(el);

    使用队列长度属性来查找队列的长度。

    fprintf('在客户端上:%i\n',q.队列长度)
    在客户端上:0

    队列长度0因为队列处理已完成。

    在本例中,使用数据队列以进度更新等待条帕弗循环。

    当您创建帕弗-loop时,将每个迭代都卸载给并行池中的工作人员。信息只有在帕弗-循环完成。您可以使用数据队列在每次迭代结束时更新等待栏。

    当您用您的进度更新等待栏时帕弗-循环时,客户端必须记录有关剩余迭代次数的信息。

    提示

    如果正在创建新的并行代码,并希望监视代码的进度,请考虑使用帕菲尔工作流。有关详细信息,请参阅使用afterEach和afterAll异步更新用户界面

    辅助函数帕弗韦巴尔酒店,更新一个等待条。这个函数使用持久的存储有关剩余迭代次数的信息。

    使用服务员要创建等待栏,W

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

    创建一个数据队列,D.然后使用之后运行帕弗韦巴尔酒店将消息发送到数据队列

    %创建数据队列和侦听器D=parallel.pool.DataQueue;在每个后面(D,@parforWaitbar);

    为您的应用程序设置迭代次数帕弗循环,N.使用等候栏W以及迭代次数N初始化函数的步骤帕弗韦巴尔酒店

    在每次迭代的末尾帕弗-循环,客户端运行帕弗韦巴尔酒店并以增量方式更新等待栏。

    N=100;帕弗韦巴尔(w,N)

    功能帕弗韦巴尔酒店使用持久变量存储客户端上已完成的迭代次数。不需要工作人员提供任何信息。

    运行一个帕弗-循环N对于这个例子,使用暂停兰德模拟一些工作。在每次迭代后,使用发送将消息发送到数据队列。当消息发送到数据队列,则等待栏更新。因为不需要工人提供任何信息,所以发送一条空消息,以避免不必要的数据传输。

    之后帕弗-循环完成后,使用删去关闭等待栏。

    帕弗i=1:N暂停(rand)发送(D,[]);终止删除(w);

    定义helper函数帕弗韦巴尔酒店.当你跑的时候帕弗韦巴尔酒店使用两个输入参数,函数初始化三个持久变量(计数,HN).当你跑的时候帕弗韦巴尔酒店只有一个输入参数,等待栏就会更新。

    作用parforWaitbar (waitbarHandle、迭代)持久的h N计数如果纳金==2%初始化计数=0;h=waitbarHandle;N=迭代次数;其他的%更新等待栏%检查句柄是否是对已删除对象的引用如果isvalid(h)count=count+1;waitbar(count/N,h);终止终止终止

    此示例显示如何使用执行并行参数扫描帕菲尔并在计算过程中使用数据队列对象。帕菲尔不会阻塞MATLAB,因此您可以在进行计算时继续工作。

    该示例对洛伦兹常微分方程组的参数进行参数扫描 σ ρ ,显示了这个系统的混乱本质。

    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网格网格函数。

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

    创建地物对象,然后设置“可见”符合事实的这样它就会在活动脚本之外的新窗口中打开。要可视化参数扫描的结果,创建一个表面图。注意,初始化Z具有创建一个空的绘图。

    身材(“可见”,真正的);表面=冲浪(ρ,σ,南(大小(σ)));包含(‘\ρ,“翻译”,“泰克斯”)伊拉贝尔(‘\σ’,“翻译”,“泰克斯”)

    建立并行环境

    方法创建一个并行工作器池帕尔普函数。

    帕尔普;
    正在使用连接到并行池的“本地”配置文件启动并行池(parpool)(工作进程数:6)。

    要从工人发送数据,创建一个数据队列对象。方法设置一个函数,在每次工作者发送数据时更新表面图之后函数。这个updatePlot函数是在示例末尾定义的支持函金宝app数。

    Q=parallel.pool.DataQueue;每次(Q,@(数据)updatePlot(表面,数据))之后;

    执行并行参数扫描

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

    帕菲尔分配工作负载时工作效率更高。若要分配工作负载,请将要浏览的参数分组到分区中。对于本例,请拆分为大小相同的分区一步通过使用冒号运算符(:)。生成的数组分割包含分区的边界。请注意,必须添加最后一个分区的端点。

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

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

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

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

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

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

    通过使用帕菲尔函数。参数扫描是一个在脚本末尾定义的帮助函数,用于在要探索的参数分区上求解Lorenz系统。它有一个输出参数,因此必须指定1.作为中的输出数帕菲尔

    对于ii=1:numel(分区)-1f(ii)=parfeval(@parameterSweep,1,分区(ii),分区(ii+1),sigma,rho,beta,Q);终止

    帕菲尔不会阻塞MATLAB,因此您可以在计算过程中继续工作。工作人员并行计算,并通过数据队列一旦他们有空。

    如果要阻止MATLAB直到帕菲尔完成后,使用等待在未来对象上的函数。使用等待当后续代码取决于帕菲尔

    等待(f);

    之后帕菲尔完成计算,等待完成后,您可以执行更多的代码。例如,绘制结果曲面的轮廓。使用获取输出函数检索存储在未来对象中的结果。

    结果=重塑(fetchOutputs(f),gridSize,[]);轮廓图(rho,sigma,results)xlabel(‘\ρ,“翻译”,“泰克斯”)伊拉贝尔(‘\σ’,“翻译”,“泰克斯”)

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

    定义辅助函数

    定义一个辅助函数,用于在要探索的参数分区上求解Lorenz系统发送功能上的数据队列对象。

    作用结果=参数扫描(第一个、最后一个、σ、ρ、β、Q)结果=零(最后一个、第一个、1);对于2 =第一:持续1 lorenzSystem = @ (t))(σ(ii) * ((2) - (1));A (1)*(rho(ii) - A (3)) - A (2);(1) *(2) -β* (3)];[t,a] = ode45(lorenzSystem,[0 100],[1 1 1]);结果=(结束,3);发送(Q, [ii,结果]);结果(ii-first + 1) =结果;终止终止

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

    作用updatePlot(surface,data) surface. zdata (data(1)) = data(2);drawnow (“限制”);终止
    R2017a中引入