罗兰在MATLAB的艺术

把想法变成MATLAB

蒙特卡罗模拟运行在多个gpu

今天我想介绍一下詹姆斯Lebak。詹姆斯是一个开发人员工作在GPU支持并行计算工具。金宝app

内容

在GPU基本期权定价

multi-GPU系统是执行的一个常见应用蒙特卡罗模拟。更多的使用gpu可以增加样本的数量,可以模拟,导致更精确的模拟。

我们先看基本期权定价的模拟并行计算工具箱例子“奇异期权定价在GPU使用蒙特卡罗方法”。在这个例子中,我们许多并发运行的模拟股票价格的演变。的均值和分布仿真输出给了我们一个股票的最终价值。

这个函数simulateStockPrice描述股票价格是一个随机微分方程的离散化。演化方程假设价格根据对数正态分布分布与无风险利率,股息收益率(如果有的话),在市场波动。

类型simulateStockPrice;
函数finalStockPrice = simulateStockPrice(上涨空间,速度,…股息,波动性,…Tfinal dT) %股票价格的离散模拟t = 0;而t < Tfinal t = t + dT;博士=(-股利波动率*波动/ 2)* dT;微扰=波动* sqrt (dT) * randn ();上涨空间=上涨空间* exp(博士+微扰);结束finalStockPrice =上涨空间;结束

实现良好的性能在GPU并行需要执行许多操作。GPU成千上万的个人计算单位,你从他们那里得到最佳性能执行成千上万或数以百万计的并行操作。这类似于我们经常给的建议vectorize在MATLAB函数更好的性能。这个函数simulateStockPrice产生一个标量输出,所以如果我们运行它,它不会实现良好的性能。

我们可以执行多次模拟在GPU上使用ARRAYFUN。的arrayfun函数接受一个函数在GPU上处理和一个gpuArray输入,并在每个元素上执行函数的输入gpuArray。这是一个替代vectorizing函数,它将需要改变更多的代码。它返回一个输出为每个元素的输入。这就是我们想做的蒙特卡罗模拟:我们想要产生许多独立输出。

runSimulationOnOneGPU函数使用arrayfun并行执行许多模拟并返回平均价格。

类型runSimulationOnOneGPU.m;
函数mfp = runSimulationOnOneGPU (Nsamples) %在GPU上运行单个股票模拟并返回%意味着文件价格在CPU上。上涨空间= 100;%股票价格起价100美元。股息= 0.01;% 1%的年度股息收益率。riskFreeRate = 0.005;% 0.5%。timeToExpiry = 2;%一生的选择。sampleRate = 1/250; % Assume 250 working days per year. volatility = 0.20; % 20% volatility. % Create the input data. Any scalar inputs are expanded to the size of the % array inputs. In this case, the starting stock prices is a vector whose % length is the number of simulations to perform on the GPU at once, and % all of the other inputs are scalars. startPrices = stockPrice*gpuArray.ones(Nsamples, 1); % Run all Nsamples simulations in parallel with one call to arrayfun. finalPrices = arrayfun( @simulateStockPrice, ... startPrices, riskFreeRate, dividend, volatility, ... timeToExpiry, sampleRate ); mfp = gather(mean(finalPrices)); end

我们执行这个函数和相对较少的样本显示计算的意思。

nSamples = 1 e6;meanFinalPrice = runSimulationOnOneGPU (nSamples);disp ([意味着最终的价格计算的num2str (meanFinalPrice)]);
计算平均最终价格是98.96

在一台机器上使用多个gpu

假设我们想运行这个模拟桌面机器上有两个gpu。这将使我们能够有更多的样品在相同的时间,由大数定律应该给我们一个更好的近似的意思是最终的股票价格。

通过并行计算工具箱,MATLAB可以在多个gpu执行计算。为了这样做,我们需要打开一个MATLAB为每个GPU池与一名工人。一个MATLAB职工需要彼此沟通GPU。

工人们在游泳池里将做所有的计算,所以客户端不需要使用gpuDevice。取消选择该设备在客户端,所以所有的内存设备是完全可用的工人。

gpuDevice ([]);

确定这台机器上有多少gpu和打开一个本地MATLAB池的大小。这给了我们一个工人为每个GPU这台机器上。

nGPUs = gpuDeviceCount ();matlabpool (“本地”,nGPUs);
matlabpool开始使用“本地”概要文件…连接到两个工人。

runSimulationOnManyGPUs函数包含一个parfor循环执行硝酸钠次了。每一次迭代的parfor循环执行nSamples独立的蒙特卡罗模拟在一个GPU和返回意味着最终的价格在所有这些模拟。整体仿真的输出是个人的意思,因为每个parfor迭代执行相同数量的独立的模拟。当循环结束执行硝石* nSamples模拟。

类型runSimulationOnManyGPUs.m;
函数[吹捧,mfp] = runSimulationOnManyGPUs (nSamples硝石)%执行总共nSamples *硝石模拟,分发%模拟在工人在matlabpool nSamples每个组。抽搐;第九parfor = 1:硝石meanFinalPrice (ix) = runSimulationOnOneGPU (nSamples);结束mfp =意味着(meanFinalPrice);兜售= toc;

运行nSamples每个GPU上迭代,我们电话runSimulationOnManyGPUs硝酸钠等于gpu的数量。

[吹捧,meanFinalPrice] = runSimulationOnManyGPUs (nSamples nGPUs);disp ([“对GPU执行模拟了”num2str(宣传),“年代”]);disp ([意味着最终的价格计算的num2str (meanFinalPrice)]);
在GPU上执行模拟了8.2226秒计算平均最终价格是98.9855

重要的是,结果是作为常规MATLAB数组而不是返回gpuArrays。如果返回的结果gpuArray然后客户端将共享一个GPU的工人,将不必要的设备上使用更多的内存,通过PCI总线传输数据。

Multi-GPU执行细节

MATLAB在使用多个GPU的推荐设置是,正如我们上面所讨论的,每个GPU打开一个工人。让我们更了解挖工人们如何与gpu交互的细节。

当工人们共享一个机器与多个GPU, MATLAB自动分配每个工人在默认情况下使用不同的GPU并行池。你可以看到通过使用spmd命令来检查每个工人所使用的设备的指数。

spmdgd = gpuDevice;idx = gd.Index;disp ([使用GPU的num2str (idx)]);结束
实验1:使用GPU 1实验室2:使用GPU 2

NVIDIA gpu可以在四种计算模式之一:默认情况下,独家线程,独家的过程,或禁止。计算模式的“ComputeMode”字段所示结构由gpuDevice返回。如果GPU在禁止模式中,没有工人会分配给使用GPU。如果在独家过程或独家GPU线程模式,只有一个MATLAB工人将尝试访问该GPU。

多个工人有可能共享相同的GPU,如果GPU在“默认”计算模式。在这样做时,GPU司机序列化访问设备。你应该知道会有性能损失,因为序列化。还会有更少的内存可用的每个工人在GPU上,因为两个或两个以上的员工将共享相同的GPU内存空间。一般很难达到良好的性能当多个工人共享相同的GPU。

您可以定制MATLAB的方式分配工人gpu来满足你自己的需求通过重写MATLAB函数selectGPU。请参阅帮助selectGPU为更多的细节。

MATLAB初始化每个工人使用不同的随机数流默认的GPU。这样做可以确保每个工人获得的值是不同的。在这个例子中,我们已经当选为简单起见使用默认的随机数生成流GPU,著名的MRG32K3A流。虽然MRG32K3A是高度重视算法具有良好的支持并行性,还有其他的流,您可以选择可以提供更好的性能。金宝app使用GPUArray描述文档页面选项控制随机数生成GPU,列出了不同的流,您可以选择。

使用多个集群gpu

所有这些细节,它的时间来考虑如何把多个gpu数亿甚至数十亿时使用模拟。可能出现这样的情况,例如,当我们想要不同的关键参数值在每个模拟波动或股息等。

假设我们想要运行8亿模拟,我们与16英伟达C2050 gpu集群可用。问题是,一个单一的GPU有有限的记忆力。一个NVIDIA C2050计算卡有3 GB的内存,可以计算的5美元\ times10 ^ 7分美元runSimulationOnOneGPU而不会耗尽内存。我们可以称之为runSimulationOnOneGPU完成所有所需的16倍模拟。在单个机器上,这样做需要大约10分钟。

我们测量的时间需要运行所有8 \ * 10 ^ 8美元与16 gpu模拟。正如您可以看到的,这个实验我们得到了近乎完美的线性扩展。

有多少你在应用程序中使用gpu,以及它们如何相互作用?让我知道的评论




发表与MATLAB®R2013a

|
  • 打印
  • 发送电子邮件

评论

留下你的评论,请点击在这里MathWorks账户登录或创建一个新的。