En función de la aplicación que se debe tener cuidado con el uso de GLCs sin tener en cuenta si las secuencias (una secuencia por hilo) se superpondrán. Podría implementar un salto con LCG, pero luego necesitaría tener un LCG de período suficientemente largo para garantizar que la secuencia no se repita.
Un ejemplo podría ser LeapFrog:
template <typename ValueType>
__device__ void leapfrog(unsigned long &a, unsigned long &c, int leap)
{
unsigned long an = a;
for (int i = 1 ; i < leap ; i++)
an *= a;
c = c * ((an - 1)/(a - 1));
a = an;
}
template <typename ValueType>
__device__ ValueType quickrand(unsigned long &seed, const unsigned long a, const unsigned long c)
{
seed = seed * a;
return seed;
}
template <typename ValueType>
__global__ void mykernel(
unsigned long *d_seeds)
{
// RNG parameters
unsigned long a = 1664525L;
unsigned long c = 1013904223L;
unsigned long ainit = a;
unsigned long cinit = c;
unsigned long seed;
// Generate local seed
seed = d_seeds[bid];
leapfrog<ValueType>(ainit, cinit, tid);
quickrand<ValueType>(seed, ainit, cinit);
leapfrog<ValueType>(a, c, blockDim.x);
...
}
Pero entonces el período de que el generador es probablemente insuficiente en la mayoría de los casos.
Para ser honesto, me gustaría utilizar una biblioteca de terceros como NAG. También hay algunos generadores de lotes en el SDK, pero probablemente eso no sea lo que está buscando en este caso.
EDITAR
Dado que esto sólo se levantó-votó, supongo que vale la pena actualizar mencionar que cuRAND, como se ha mencionado por respuestas más recientes a esta pregunta, que está disponible y proporciona una serie de generadores y distribuciones. Ese es definitivamente el lugar más fácil para comenzar.
Alguna información útil: http://http.developer.nvidia.com/GPUGems3/gpugems3_ch37.html – Jesper