Mathematica/CUDA 减少执行时间

3
我正在编写一个简单的蒙特卡罗粒子输运模拟程序。我的方法是编写一个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()函数 -> 我能否为所有线程调用此函数一次?
  2. 内核向Mathematica返回一个非常大的实数数组(100,000)。 我知道,CUDA的瓶颈是GPU和CPU之间的通道带宽。 我只需要列表元素的总和,因此在GPU中计算列表元素的总和并发送一个实数到CPU会更有效。

你不能使用 CUDATotal 吗? - b.gatessucks
“CUDATotal”将在结果数组被复制回CPU内存后执行。我想避免将整个结果数组复制到CPU内存中。我认为解决方案必须在代码的C部分中。谢谢您的回复。 - user1961006
如果是这样,我完全误解了关于此的文档说明;感谢您的回复。 - b.gatessucks
2个回答

0

1) 如果您需要为所有线程执行curand_init(),您是否可以在CPU上执行此操作并将其作为参数传递给CUDA?

2) 如果有一个 "device float sumTotal" 函数来求和并返回值,那么您是否已经将尽可能多的*传输数据复制到共享内存缓冲区中了?


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接