Pergunta

Eu tenho algum código Fortran90 paralelo em que cada thread precisa para gerar a mesma sequência de números aleatórios.

Eu tenho um gerador de números aleatórios que parece ser thread-seguro, uma vez que, para uma determinada semente, eu sou completamente incapaz de repetir os mesmos resultados cada vez que eu executar o programa.

Eu surfei sem sucesso (quase) toda a web à procura de algum código de um RNG thread-safe. Alguém poderia me fornecer (o link para) o código de um?

Agradecemos antecipadamente!

Foi útil?

Solução

Um bom Pseudorandom gerador de números para Fortran90 pode ser encontrada no Intel Math Kernel Vector estatística Biblioteca . Eles são thread-safe. Além disso, por que ele precisa ser threadsafe? Se você quiser cada thread para obter a mesma lista, instanciar um novo PRNG para cada segmento com a mesma semente.

Outras dicas

A maioria dos geradores de números aleatórios repetíveis precisa estado de alguma forma. Sem estado, eles não podem fazer o que vem a seguir. Para ser thread-safe, você precisa encontrar uma maneira de agarrar o estado-se (isto é, não pode ser global).

Quando você diz "necessidades para gerar a mesma sequência de números aleatórios" que quer dizer que

  • Cada segmento precisa gerar um fluxo de números idênticos para o outro segmento? Isto implica a escolha da semente antes de descascar fios, em seguida, instanciar a um PRNG segmento local em cada segmento com a mesma semente.

ou

  • Você quer ser capaz de repetir a mesma sequência de números entre diferentes execuções dos programas, mas cada thread gera a sua própria sequência autónoma? Neste caso, você ainda não pode compartilhar um único PRNG porque a seqüência de operação de rosca é não-determinista. Então semear um único PRNG com uma semente conhecida antes tópicos lançamento, e usá-lo para gerar as sementes iniciais para os fios. seguida Você geradores de segmento local instanciar em cada thread ...

Em cada um desses casos, você deve observar o que Neil Butterworth dizer sobre as estatísticas: a maioria das garantias usuais que o PRNG como a reivindicação são não confiável quando mix córregos gerado desta maneira.


Em ambos os casos você precisa de um PRNG segmento local. Eu não sei o que está disponível no f90 ... mas você também pode escrever você possui (lookup Mersenne Twister , e escrever um routne que leva o estado salvo como um parâmetro ...).

Em Fortran 77, este seria algo parecido

      function PRNGthread (state)

      double state(statesize)

c stuff happens here which uses and manipulates the state vector...

      PRNGthread = result
      return 

e cada um dos seus segmentos devem manter um vetor de estado separado, embora todos usarão o mesmo valor inicial.

Eu entendo que você precisa cada fio para produzir o mesmo fluxo de números aleatórios.

Um bom Pseudo gerador aleatório que irá gerar um fluxo reproduzível de números e é bastante rápido é o MT19937 . Apenas certifique-se que você gera a semente antes da desova fora dos tópicos, mas gerar uma instância separada do MT em cada thread (fazer a instância do segmento MT local). Dessa forma, será garantido que cada MT irá produzir o mesmo fluxo de números.

Como sobre Sprng ? Eu não tentei me embora.

Eu codificado um Fortran 90 versão thread-safe da Mersenne Twister / MT19973. O estado do PRNG é salvo em um tipo derivado (randomNumberSequence), e você usar procedimentos para semear o gerador ou obter o elemento seguinte na sequência.

http: //code.google.com/p/i3rc-monte-carlo-model/source/browse/trunk/Code/RandomNumbersForMC.f95

As alternativas parecem ser:

  • Use um objeto de sincronização (como uma extensão mútua) sobre as sementes do gerador valor. Esta, infelizmente, publicando seu código em acessos gerador
  • Use o armazenamento de segmento local no gerador de modo que cada segmento tem sua própria semente - o que pode causar statstical problemas para a sua aplicação
  • Se a sua plataforma suporta uma adequada operação atômica, use esse no semente (que provavelmente não vai, no entanto)

Não é uma lista muito encorajador, eu sei. E para adicionar a ele, eu não tenho nenhuma idéia de como implementar qualquer um deles em Fortran!

Este artigo https://www.cmiss.org/openCMISS/wiki/RandomNumberGenerationWithOpenMP não só link para uma implementação Fortran, mas menciona pontos-chave necessários para fazer uma utilizável PRNG com threads. O ponto mais importante é:

A versão Fortran90 de Zigurate tem várias variáveis ??e matrizes com o atributo 'SAVE'. A fim de paralelizar o RNG uniforme, então, parece que as mudanças são necessárias para fazer essas variáveis ??arrays com um valor separado para cada thread (cuidado com o falso compartilhamento). Então, quando a função PRNG é chamado, devemos passar o número do segmento, e usar o valor do estado correspondente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top