主要内容

Parfeval 21点

本例使用并行计算工具箱™来玩21点纸牌游戏,也称为21。我们模拟一些玩家,他们一次独立地玩数千手牌,并显示收益统计数据。此示例在并行工作池上异步运行模拟,使用parfeval.通过这种方式,我们可以在结果可用时更新结果的显示。

相关例子:

你可以在函数中找到本例所示的代码:

函数paralleldemo_blackjack_parfeval

分析顺序问题

因为21点玩家是相互独立的,所以我们可以并行模拟他们。为此,我们将问题划分为许多函数求值。我们最多运行numPlayers模拟,每个玩家都在玩游戏numHands21点牌。一旦结果可用,我们就绘制结果,如果经过的时间超过,我们就终止模拟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

结束