1903-Python计算-欧式期权-CUDA篇

论坛 期权论坛 期权     
青梧公子   2019-5-24 03:02   4994   0
前一篇,1903-Python计算-欧式期权-CPU篇,主要是写用CPU做蒙特卡洛模拟,这一篇写用GPU(显卡中的那个芯片)做计算。
为什么要用GPU计算呢?先给结论,因为性价比。上一篇用CPU为8250U的Surface Pro 6, 计算300万条路径耗时9.34秒,本文后文用GTX 1060显卡,效率可以提升大约5倍,而成本不超过1500元。
假如说我们纯粹用CPU来达到8倍速度的效果,即使用当今最快的
Intel Core i9-9960X也无法达到(由于蒙特卡洛模拟良好的并行特性,因此可以参考cpubenchmark.net的评分数据计算速度,8250U评分7600分,9960X评分29000分,才3.8倍,需要买两块9960X,组成双CPU系统才能达到这个速度),某东上,一块9960X价格大概是的1.5万,都够去买一块2080Ti的显卡了,其性能可以是1060的两倍(1060评分约9000分,2080Ti约17000分)。由此可见,至少对于本文要解决的问题而言,给定预算,用显卡计算比用CPU计算可以更快。
效率的提升总是要付出代价的。GPU编程难度比CPU高很多,看如下GPU的结构图就会发现,它里面的核心(每个绿色的小方块就是一个计算核心)很多而又很小,例如我即将用的1060 6G显卡有1280个小核心。


在上一篇中,我们将CPU比比作几个计算能力强大的大学生,我们也讨论了如何让这些核心同时进行计算(并行计算),难度就已经不低;而GPU里面这一千多个小核心,就像是一千多个小学生,单个计算能力肯定比不上CPU里面的大学生,只有通过让他们同时协作,这样才能超过CPU的速度,而同时指挥一千多个不那么听话的小学生可不是一件容易的事情。
由此可见,GPU计算,需要找到合适的问题,同时要特殊的编程方法驱动尽可能全部的小核心一起做运算。从这个角度讲,蒙特卡洛模拟非常适合运用于GPU计算,例如假设需要计算1000条路径,可以让每个小核心负责一条路径即可。
GPU编程除了需要跟CPU编程不一样的算法设计,还要掌握不一样的编程语言。之前两大类型,一是CUDA,只能适用于Nvidia的显卡;二是OpenCL,理论上可以适用于Nvidia和AMD两类显卡。几年前,OpenCL打着开源的牌子推广,而且由于可以用在便宜的AMD显卡上,于是我就被骗了,走了很长一段弯路。主要是因为OpenCL的社区支持太不完全,甚至连生成随机数都要自己写底层函数,自己写得函数太多,稳定性就不好把握了,记得当时我写了一套计算分级A的函数,由于CPU计算太慢,就写了OpenCL版本,费尽力气从底层函数写起,计算结果是没错,但每次运行10多分钟后就导致显卡驱动崩溃。
本文我们就不用OpenCL了,而是选用Cuda,显卡选用的是当前便宜的中端GTX1060 6GB显卡;在Python中的Cuda编程可以有几种选择,最纯粹的当然是自己写核函数,但之前OpenCL的经验让我有些心有余悸,于是这里我选用Numba中自带的Cuda JIT编译模式。
Imports部分:


用两个函数来完成计算,一个供Numba编译成Cuda内码的部分,一个是用于调用这个内码的Python函数:

调用这个函数的语句格式是:
  1. (call3, put3, std3)=cudaopt(S0,K,r,T,sig,N*100)
复制代码
由于计算速度很快,因此这里我们把计算的路径数量从300万条增加到了3亿条。经测试,耗时58秒。不过,这里Cuda计算得到的是单精度数据,上一篇文章CPU计算得到的是双精度数据,如果要放在一个标准下比较,可以换算认为CPU的单精度速度比双精度快1倍,由此可以认为Cuda版本的速度是CPU的:100*9.34/58/2=8 倍。
这应该算是最简单的一个Cuda程序了。如果是的路径依赖型期权计算,程序基础框架可以不用改,只要往Cuda代码部分加入路径判断的语句就行。届时,将会面临一个很麻烦的问题,举例而言,现在我们是指挥1000个小学生,同时做一个运算,后面我们要他们差异化,有的人要做加法,有的人做减法。在CPU里面,不同核心加法和减法可以同时计算,但Cuda里面,同一时间只能做相同的一个运算,例如要做完加法才能做减法,会导致部分核心闲置。
好了,简单的Cuda程序到此结束,后期将往两个方向发展,一是,从单机并行扩展到多台机器异构并行计算,二是,从最简单的欧式期权扩展到路径依赖型品种。
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:20
帖子:4
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP