Mathematica / CUDA减少了执行时间

时间:2013-01-09 13:37:28

标签: c++ c cuda wolfram-mathematica montecarlo

我正在为粒子传输编写一个简单的蒙特卡罗模拟。我的方法是为CUDA编写内核并将其作为Mathematica函数执行。

内核:

#include "curand_kernel.h"
#include "math.h"

extern "C" __global__ void monteCarlo(Real_t *transmission, mint seed, mint pathN) {
curandState rngState;

int index = threadIdx.x + blockIdx.x*blockDim.x;

curand_init(seed, index, 0, &rngState);

if (index < pathN) {
    //-------------start one packet run----------------------

    float packetWeight = 1.0;
    int m = 0;

    while(packetWeight > 0.0){

        //MONTE CARLO CODE

        // Test: still in the sample?
            if(z_coordinate > sampleThickness){
                packetWeight = 0;
                z_coordinate = sampleThickness;
                transmission[index]=1;
            }
        }
    }
    //-------------end one packet run------------------------
}
}

Mathematica代码:

Needs["CUDALink`"];
cudaBM = CUDAFunctionLoad[code, 
"monteCarlo", {{_Real, "Output"}, _Integer, _Integer}, 256, 
"UnmangleCode" -> False];


pathN = 100000;
result = 0;  (*count for transmitted particles*)
For[j = 0, j < 10, j++,
   buffer = CUDAMemoryAllocate["Float", 100000];
   cudaBM[buffer, 1490, pathN];
   resultOneRun = Total[CUDAMemoryGet[buffer]];
   result = result + resultOneRun;
];

到目前为止,一切似乎都有效,但与没有CUDA的纯C代码相比,速度的提升是微不足道的。我有两个问题:

  1. curand_init()函数由每个汇总步骤开始时的所有线程执行 - &gt;我能为所有线程调用一次这个函数吗?
  2. 内核向Mathematica返回了一大堆实数(100 000)。我知道,CUDA的瓶颈是GPU和CPU之间的通道带宽。我只需要列表中所有元素的总和,因此计算GPU中列表元素的总和并仅向CPU发送一个实数会更有效。

2 个答案:

答案 0 :(得分:0)

1)如果你需要为所有线程执行一次curand_init(),你可以在CPU中执行该操作并将其作为参数传递给CUDA吗?

2)&#34; 设备如何浮动sumTotal&#34;汇总并返回您的值的函数?您是否已将尽可能多的*传输数据复制到共享内存缓冲区中?

答案 1 :(得分:0)

根据CURAND文档, “调用curand_init()比调用curand()或curand_uniform()要慢。对curand_init()的大偏移比较小的偏移需要更多的时间。保存和恢复随机生成器状态比重复重新计算起始状态要快得多。 。“

http://docs.nvidia.com/cuda/curand/index.html#topic_1_3_4

另外请查看此主题以获取更多详细信息 CUDA program causes nvidia driver to crash