Я пытаюсь сгенерировать «случайные» числа из равномерного распределения внутри ядра CUDA __global__
, используя два разных подхода. Первый использует cuRAND
API устройства, а второй - thrust
. Для каждого подхода я создал свой класс.
Вот мое cuRAND
решение:
template<typename T>
struct RNG1
{
__device__
RNG1(unsigned int tid) {
curand_init(tid, tid, 0, &state);
}
__device__ T
operator ()(void) {
return curand_uniform(&state);
}
curandState state;
};
А вот мое thrust
решение:
template<typename T>
struct RNG2
{
__device__
RNG2(unsigned int tid)
: gen(tid)
, dis(0, 1) { gen.discard(tid); }
__device__ T
operator ()(void) {
return dis(gen);
}
thrust::default_random_engine gen;
thrust::uniform_real_distribution<T> dis;
};
Я использую их следующим образом:
template<typename T> __global__ void
mykernel(/* args here */)
{
unsigned int tid = blockIdx.x * blockDim.x + threadIdx.x;
RNG1<T> rng(tid);
// or
RNG2<T> rng(tid);
T a_random_number = rng();
// do stuff here
}
Оба они работают, но решение cuRAND
намного медленнее (более чем в 3 раза медленнее). Если я установлю второй параметр curand_init
(порядковый номер) на 0, то производительность будет такой же, как у решения thrust
, но случайные числа будут «плохими». Я вижу шаблоны и артефакты в результате распределения.
Вот мои два вопроса:
- Может кто-нибудь объяснить мне, почему решение
cuRAND
с ненулевой последовательностью медленнее? - Как можно
thrust
Быть так же быстро, как cuRAND
с нулевой последовательностью, но также генерировать хорошие случайные числа? - При поиске в Google я заметил, что большинство людей используют
cuRAND
, и очень немногие используют thrust
для генерации случайные числа внутри кода устройства. Есть ли что-то, о чем я должен знать? Я неправильно использую thrust
?
Спасибо.