Mathematica / CUDA сокращают время выполнения

Я пишу простой симулятор Монте-Карло для переноса частиц. Мой подход — написать ядро ​​для 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;
];

Кажется, что пока все работает, но улучшение скорости по сравнению с чистым кодом C без CUDA незначительно. У меня две проблемы:

  1. функция curand_init () выполняется всеми потоками в начале каждого шага суммирования -> можно ли вызвать эту функцию один раз для всех потоков?
  2. ядро возвращает Mathematica очень большой массив реалов (100 000). Я знаю, что узким местом CUDA является пропускная способность канала между GPU и CPU. Мне нужна только сумма всех элементов списка, поэтому было бы более эффективно вычислить сумму элементов списка в GPU и отправить только одно действительное число в CPU.

3

Решение

1) Если вам нужно выполнить curand_init () один раз для всех потоков, можете ли вы просто сделать это в ЦП и передать это в качестве аргумента CUDA?

2) Как насчет «устройство float sumTotal «функция, которая суммирует и возвращает ваши значения? Вы скопировали столько * данных передачи в буфер общей памяти?

0

Другие решения

Согласно документам CURAND,
«Вызовы curand_init () медленнее, чем вызовы curand () или curand_uniform (). Большие смещения для curand_init () занимают больше времени, чем меньшие смещения. Гораздо быстрее сохранять и восстанавливать случайное состояние генератора, чем повторно пересчитывать начальное состояние «.

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

Также, пожалуйста, загляните в эту тему для более подробной информации
Программа CUDA вызывает сбой драйвера nvidia

0

По вопросам рекламы [email protected]