Normalmente, quando eu proponho um gerador seqüencial de números aleatórios em C, uso a chamada
srand(time(NULL))
então use
rand() mod N
para obter um número inteiro aleatório entre 0 e N-1. No entanto, quando faço isso em paralelo, as chamadas ao tempo (NULL) são tão próximas uma da outra que acabam sendo exatamente o mesmo número.
Eu tentei usar um gerador de números aleatórios congruencial linear:
para alguns inteiros e .
Eu sei que escolher para um número inteiro grande produz resultados rápidos porque o operador do módulo pode ser calculado truncando dígitos. No entanto, acho difícil estabelecer sementes que produzam seqüências aleatórias com um grande período em paralelo. Eu sei que a duração de um período é máxima se
- c e m são números primos entre si
- a-1 é divisível por todos os fatores primos de m
- se m for múltiplo de 4, a-1 também deverá ser múltiplo de 4.
(fonte: wikipedia )
Mas como garantir que todos os fluxos de números aleatórios tenham essa propriedade máxima? Em termos de MPI, como incorporar rank
e size
produzir períodos máximos usando o método congruencial linear? Seria mais fácil usar um Fibonacci Lagged ou Mersenne Twister para produzir fluxos aleatórios paralelos mais longos?
mod
os bits de baixa ordem - como sugeriu Jonathan Dursi , eles são muito menos aleatórios. Em vez disso, divida seu número aleatório (int) por maxint / range para obter o range necessário. Custa uma divisão, mas provavelmente é uma opção mais barata para melhorar a qualidade do seu fluxo de números aleatórios do que mudar para outro PRNG.