Parfeval 21点
本例使用并行计算工具箱™来玩21点纸牌游戏,也称为21。我们模拟一些玩家,他们一次独立地玩数千手牌,并显示收益统计数据。此示例在并行工作池上异步运行模拟,使用parfeval
.通过这种方式,我们可以在结果可用时更新结果的显示。
相关例子:
你可以在函数中找到本例所示的代码:
函数paralleldemo_blackjack_parfeval
分析顺序问题
因为21点玩家是相互独立的,所以我们可以并行模拟他们。为此,我们将问题划分为许多函数求值。我们最多运行numPlayers
模拟,每个玩家都在玩游戏numHands
21点牌。一旦结果可用,我们就绘制结果,如果经过的时间超过,我们就终止模拟maxSimulationTime
秒,或者如果用户取消执行。
numPlayers = 100;numHands = 5000;maxSimulationTime = 20;
将工作划分为单独的功能评估
我们称之为parfeval
函数请求对并行池工作程序的模拟进行评估。如果需要,将自动创建并行池。的parfeval
函数返回平行的。未来
对象,当结果可用时,我们使用该对象访问结果。你可以查看pctdemo_task_blackjack的代码详情如下。
为idx = numPlayers:-1:1期货(idx) = parfeval(@pctdemo_task_blackjack, 1, numHands, 1);结束创建一个onCleanup以确保我们退出时不会留下任何正在运行的期货%这个例子。cancelFutures = onCleanup(@() cancel(futures));
设置用于收集结果和监控进度
平行泳池的工作人员立即开始奔跑pctdemo_task_blackjack
,我们可以在得到结果后立即收集和显示结果fetchNext
方法。我们使用resultsSoFar
积累成果。我们更新数组完成
指明…的元素期货
是否已完成,并增加计数器numCompleted
.我们提供可选参数超时
到fetchNext
方法,以便在没有新结果可用时快速返回。
resultsSoFar = 0 (numHands, numPlayers);为所有结果分配空间completed = false(1, numPlayers);一个给定的将来是否已经完成超时= 2;% fetchNext超时时间(秒)numCompleted = 0;已完成多少次模拟图= pctdemo_setup_blackjack(1);创建一个图形以显示结果使用appdata跟踪,创建一个带取消按钮的等待栏%是否已按下取消按钮。hWaitBar = waitbar(0,“21点进步”,“CreateCancelBtn”,...@(src, event) setappdata(gcbf()“取消”,真的));setappdata (hWaitBar“取消”、假);
收集并显示可用的结果
我们通过调用来收集和显示结果fetchNext
在一个循环中,直到我们看到numPlayers
结果。当fetchNext
返回新结果,我们将结果赋值到resultsSoFar
,更新完成
数组和numCompleted
反击,并更新情节。如果用户按下等待栏上的取消按钮,则循环将提前终止maxSimulationTime
到期。
startTime = clock();而numCompleted < numPlayers% fetchNext将阻塞执行,直到期货的一个元素完成。它%然后将该指数返回到已完成的元素的期货中,%和执行结果。[completedIdx, resultThisTime] = fetchNext(期货,timeout);如果fetchNext超时返回一个空的completedIdx,不要尝试%处理结果。如果~isempty(completedIdx) numCompleted = numCompleted + 1;已完成期货的更新列表。complete (completedIdx) = true;填写部分结果。resultsSoFar(:, completedIdx) = resultThisTime;%更新绘图。pctdemo_plot_blackjack(fig, resultsSoFar(:, completed), false);结束看看我们是否已经超时了。。timeElapsed = etime(clock(), startTime);如果timeElapsed > maxSimulationTime'模拟终止:maxSimulationTime已超过。\n');打破;结束检查是否按下了取消按钮。如果getappdata (hWaitBar“取消”)流(“模拟取消。\ n”);打破;结束更新等待栏。fractionTimeElapsed = timeElapsed / maxSimulationTime;fractionPlayersCompleted = numCompleted / numPlayers;fractionComplete = max(fractionTimeElapsed, fractionPlayersCompleted);waitbar (fractionComplete hWaitBar);结束流('完成的模拟次数:%d\n', numCompleted);现在模拟完成,我们可以取消期货和删除服务员。取消(期货);删除(hWaitBar);
模拟终止:超过maxSimulationTime。完成的模拟次数:74
结束