以编程方式收集池监控数据
池监控数据可帮助您了解池工作单元如何在并行池上执行并行构造,例如 parfor
、parfeval
和 spmd
。监控数据包括有关工作单元如何执行并行代码以及相关数据传输的信息。这些信息可帮助您识别瓶颈、平衡工作负载、确保资源利用效率,并优化并行代码的性能。
您可以使用 ActivityMonitor
对象以编程方式收集池活动监控数据,或使用并行池仪表板以交互方式收集数据。对于大多数工作流,请使用并行池仪表板进行交互式收集和查看监控数据。但是,如果您需要收集监控数据以供日后审查或用于在并行批处理池上运行的代码,请使用 ActivityMonitor
对象。
收集交互式并行池的监控数据
此示例展示了如何使用 ActivityMonitor
对象收集交互式并行池上的监控数据。
创建一个具有三个工作单元的并行池。
nWorkers = 3; pool = parpool(nWorkers);
Starting parallel pool (parpool) using the 'Processes' profile ... Connected to parallel pool with 3 workers.
收集并分析监控数据
创建一个 ActivityMonitor
对象,开始收集池监控数据。
monitor = parallel.pool.ActivityMonitor;
运行您的并行代码。为了便于理解,本示例使用一个简单的 parfor
循环来遍历一系列值。
values = [5 12 13 1 12 5]; parfor (idx = 1:numel(values),3) u = rand(values(idx)*3e4,1); out(idx) = max(conv(u,u)); end
代码执行完成后,停止收集监控数据,并获取在 parfor
执行期间收集的池监控结果。
monitoringResults = stop(monitor);
在并行池仪表板中可视化监控结果。parpoolDashboard
函数打开“并行池仪表板”,并在 ActivityMonitorResults
对象 monitoringResults
中显示监控结果。
parpoolDashboard(monitoringResults)
通常,比较工作单元的执行时间可以帮助您识别代码中的瓶颈。时间轴图形直观地显示了工作单元和客户端执行 parfor
循环并传输数据所花费的时间。深蓝色表示运行 parfor
循环所花费的时间,浅蓝色表示发送数据所花费的时间,品红色表示接收数据所花费的时间。
您可以看到,与其他工作单元相比,一些工作单元完成迭代所需的时间明显更长,导致工作单元在大部分 parfor
执行时间内处于空闲状态。这表明负载在工作单元之间分配不均匀。
改进并行代码
如果您知道 parfor
循环中每个迭代的工作量,则您可以使用 parforOptions
来控制将迭代划分为工作单元子范围。有关详细信息,请参阅parforOptions
。
在此示例中,values
的值越大,迭代的计算量就越大。values
中的每对连续的值平衡了低计算强度和高计算强度。为了更好地分配工作量,创建一组 parfor
选项,将 parfor
迭代划分为 2
大小的子范围。
opts = parforOptions(pool,RangePartitionMethod="fixed",SubrangeSize=2);
创建一个 ActivityMonitor
对象,开始收集池监控数据。
monitor = parallel.pool.ActivityMonitor;
运行与之前相同的代码。要使用 parfor
选项,请将它们传递给 parfor
的第二个输入参量。
parfor (idx = 1:numel(values),opts) u = rand(values(idx)*3e4,1); out(idx) = max(conv(u,u)); end
检索监控结果并在并行池仪表板中可视化展示结果。
monitoringResults = stop(monitor); parpoolDashboard(monitoringResults)
在时间轴图中,比较工作单元的执行时间。请注意,在第二个 parfor
循环中,每个工作单元执行 parfor
迭代所需的时间大致相同,没有空闲的工作单元。现在工作量已经得到更好的分配。
收集批并行池的监控数据
此示例展示了如何使用 ActivityMonitor
对象收集批处理作业并行池中的监控数据。
使用 parfeval
函数定义一个函数,对不同的美元拍卖模型进行仿真。该函数创建一个 ActivityMonitor
对象来收集监控数据,提交并等待 parfeval
计算,然后检索池监控结果。
function monitoringResults = runDollarAuctionModels % Define simulation parameters params.nPlayers = 20; params.incr = 0.05; params.dropoutRate = 0.01; params.nTrials = 1000; params.coalitionProbability = 0.5; params.riskRange = [0.5 2]; % Define a list of model functions to run modelFunctions = {@mcDollarAuction,@mcCollabDollarAuction,@mcRiskAverseDollarAuction}; numModels = length(modelFunctions); % Create an ActivityMonitor object to collect monitoring data monitor = parallel.pool.ActivityMonitor; % Use parfeval to simulate each model in parallel f(1:numModels) = parallel.FevalFuture; for m = 1:numModels f(m) = parfeval(modelFunctions{m},1,params); end wait(f); % Stop the activity monitor and retrieve the results collected monitoringResults = stop(monitor); end
将 runDollarAuctionModels
函数作为批处理作业运行,等待批处理作业完成。
job = batch(@runDollarAuctionModels,1,Pool=4,CaptureDiary=false); wait(job);
从已完成的批处理作业中获取监控结果。
out = fetchOutputs(job); monitoringResults = out{1};
在并行池仪表板中可视化监控结果。
parpoolDashboard(monitoringResults)
探索并行池监控数据
在“并行池仪表板”中,时间轴图表示工作单元运行并行代码和传输数据所花费的时间。黄色表示执行 parfeval
计算所花费的时间,浅蓝色表示发送数据所花费的时间,而品红色表示接收数据所花费的时间。观察时间线图表,您可以看到其中一个 parfeval
柱状图比其他柱状图更长。要查看该 parfeval
计算的具体信息,请点击该栏。
时间轴图和并行构造、摘要以及工作单元摘要表现在显示所选 parfeval
计算的特定信息。您可以在并行构造表的详细信息列中识别所选的 parfeval
计算正在运行的函数。
要清除当前选定的 parfeval
计算的信息并再次查看所有工作单元的活动数据,在“并行池仪表板”的选择部分中,选择清除选择。
另请参阅
函数
parfor
|parfeval
|stop
|parforOptions