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 コードと比較した速度の向上はごくわずかです。2 つの問題があります。

  1. curand_init() 関数は、すべての計算ステップの開始時にすべてのスレッドによって実行されます -> すべてのスレッドに対してこの関数を 1 回呼び出すことはできますか?
  2. カーネルはMathematica に非常に大きな実数の配列(100 000)を返します.CUDA のボトルネックは、GPU と CPU 間のチャネル帯域幅であることはわかっています。リストのすべての要素の合計のみが必要なため、GPU でリスト要素の合計を計算し、実数を 1 つだけ CPU に送信する方が効率的です。
4

2 に答える 2

0

CURAND ドキュメントによると、「curand_init() の呼び出しは、curand() または curand_uniform() の呼び出しよりも遅くなります。curand_init() への大きなオフセットは、小さなオフセットよりも時間がかかります。乱数発生器の状態を保存して復元するよりも、はるかに高速です。開始状態を繰り返し再計算します。」

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

また、詳細については、このスレッドを参照してください 。CUDA プログラムにより nvidia ドライバーがクラッシュする

于 2013-01-09T19:44:43.920 に答える
0

1) すべてのスレッドに対して curand_init() を 1 回実行する必要がある場合、CPU でそれを実行し、それを引数として CUDA に渡すことができますか?

2) 値を合計して返す " device float sumTotal" 関数はどうですか? *送信データを共有メモリ バッファにコピーしましたか?

于 2013-01-09T14:45:04.073 に答える