Optimization 基于CUDA的蒙特卡罗优化

Optimization 基于CUDA的蒙特卡罗优化,optimization,cuda,gpu,montecarlo,Optimization,Cuda,Gpu,Montecarlo,我正在处理一些关于我在CUDA中开发的蒙特卡罗模拟的缓慢问题。我观察到GTX 680 compute capability 3.0的性能非常差,我不知道我实现蒙特卡罗模拟的方式有什么问题。我试图通过在主循环中执行几个路径来“展开”我的循环,但没有观察到任何显著的改进 我已将我的内核定义如下: SimulationVolInterp=parallel.gpu.CUDAKernel'sh_cuda_MC.ptx','sh_cuda_MC.cu','MCSharedMemory'; Simulatio

我正在处理一些关于我在CUDA中开发的蒙特卡罗模拟的缓慢问题。我观察到GTX 680 compute capability 3.0的性能非常差,我不知道我实现蒙特卡罗模拟的方式有什么问题。我试图通过在主循环中执行几个路径来“展开”我的循环,但没有观察到任何显著的改进

我已将我的内核定义如下: SimulationVolInterp=parallel.gpu.CUDAKernel'sh_cuda_MC.ptx','sh_cuda_MC.cu','MCSharedMemory'; SimulationVolInterp.ThreadBlockSize=2^9; SimulationVolInterp.GridSize=2^5

这是我的内核函数:

__global__ void MC(double* vol_int, double* matrice,const double* randomWalk, int nbreSimulation, int nPaths, double S0, double strike, double T, double drift,  const double* strikes_vec, const double* volatility_mat, int l_strikes_vec) {

    //double mydt = (index - nbreSimulation)/nbreSimulation*dt + dt;
    double dt = T/nPaths;
    unsigned int tid = threadIdx.x + blockDim.x * blockIdx.x; 
   // unsigned int stride = blockDim.x*gridDim.x;
    unsigned int index = tid;   
    int workingCol = 0; 
    unsigned int previousMove;  
    if (index < nbreSimulation) {
        matrice[index] = S0;  
        for (workingCol=1; workingCol< nPaths; workingCol++) {
            previousMove = index; 
            index += nbreSimulation;
            vol_int[index] = 0.25;
            matrice[index] = matrice[previousMove]*exp((drift - vol_int[index] *vol_int[index] *0.5)*dt + randomWalk[index]*vol_int[index] *sqrt(dt));
        }
   }
}    
例如,2^12个模拟x 2^11个步骤需要7秒,这相当大,对吧?! 我在Matlab上的经典Monte Carlo只花了不到一秒的时间

有人能在这一点上帮助我吗


非常感谢

GTX 680上双精度算法的性能并没有那么好。我记得在2012年GTC上,一位Nvidia工程师告诉我,GTX 680的双精度FPU比单精度FPU少得多。这张卡是为游戏而不是计算而优化的

这个沼泽柱
证实了传闻证据。尝试新的GTX Titan卡或尝试单精度蒙特卡罗模拟,我怀疑这两个选项都不太适合您。

GTX 680上的双精度算法性能不太好。我记得在2012年GTC上,一位Nvidia工程师告诉我,GTX 680的双精度FPU比单精度FPU少得多。这张卡是为游戏而不是计算而优化的

这个沼泽柱
证实了传闻证据。尝试新的GTX Titan卡或尝试单精度蒙特卡罗模拟,我怀疑这两个选项都不太适合您。

将双精度替换为浮动。双精度工作正常,仅cuda 3.5取代双精度浮动。非常好,只有cuda 3.5

你不能将volu int初始化为0.25,甚至不使用数组吗?我认为这可能会有更好的结果。此外,这种计算方式高度依赖于前面的步骤,因此请尝试在这里考虑一个折衷方案,如果您将计算拆分为一大块,您将牺牲您的性能,因为GPU时钟比CPU时钟少得多。你必须有一个大规模并行算法,你的指令应该很简单,我不认为给一个线程分配2^11个步骤是个好主意。谢谢你的回答。实际上,我简化了我的代码常量波动率,但我在每一步计算一个新的波动率。实际上,我真的不知道如何继续分割每个线程的作业。在我看来,2^11步骤必须由一个线程执行,以避免并发访问权限?我在CUDA中看到的所有有关蒙特卡罗模拟的示例都做了相同的事情:一个线程计算一次模拟的所有步骤。是的,您的代码高度依赖于它以前的步骤,我也看不到任何进一步拆分它的方法,但是想象一下单个线程必须执行2^11个步骤!当然,CPU可以更快地完成这项工作,但在这种情况下,有2^12个CPU可以同时运行,显然至少对于您的硬件来说,这种折衷是没有意义的。这很烦人:/I我真的不知道如何继续。即使在2^6个步骤上,我的程序也比CPU代码2^7个线程慢。我看不出我的算法/实现有什么问题。我应该能打败CPU/难道你不能将volu_int初始化为0.25,甚至不使用数组吗?我认为这可能会有更好的结果。此外,这种计算方式高度依赖于前面的步骤,因此请尝试在这里考虑一个折衷方案,如果您将计算拆分为一大块,您将牺牲您的性能,因为GPU时钟比CPU时钟少得多。你必须有一个大规模并行算法,你的指令应该很简单,我不认为给一个线程分配2^11个步骤是个好主意。谢谢你的回答。实际上,我简化了我的代码常量波动率,但我在每一步计算一个新的波动率。实际上,我真的不知道如何继续分割每个线程的作业。在我看来,2^11步骤必须由一个线程执行,以避免并发访问权限?我在CUDA中看到的所有有关蒙特卡罗模拟的示例都做了相同的事情:一个线程计算一次模拟的所有步骤。是的,您的代码高度依赖于它以前的步骤,我也看不到任何进一步拆分它的方法,但是想象一下单个线程必须执行2^11个步骤!当然,CPU可以更快地完成这项工作,但在这种情况下,有2^12个CPU可以同时运行,显然至少对于您的硬件来说,这种折衷是没有意义的。这很烦人:/I我真的不知道如何继续。即使在2^6个步骤上,我的程序也比CPU代码2^7个线程慢。我看不出我的算法/imp有什么问题 营养素。我应该能打败CPU/