Frage

Ich habe einige parallel Fortran90 Code, in dem jeder Thread die gleiche Folge von Zufallszahlen zu erzeugen braucht.

Ich habe einen Zufallszahlengenerator, der für einen bestimmten Samen da, faden unsicher zu sein scheint, ich bin völlig unfähig, die gleichen Ergebnisse jedes Mal, wenn ich das Programm ausführen zu wiederholen.

Ich surfte ohne Erfolg (fast) die gesamte Bahn für einigen Code eines Thread-sicher RNG suchen. Kann mir jemand mit (den Link) bieten den Code ein?

Vielen Dank im Voraus!

War es hilfreich?

Lösung

Eine gute Pseudo-Zufallszahlengenerator Fortran90 kann in der Intel Math Kernel Vector Statistische Bibliothek . Sie sind Thread-sicher. Auch, warum braucht es THREAD zu sein? Wenn Sie jeden Thread wollen die gleiche Liste zu bekommen, instanziiert ein neues PRNG für jeden Thread mit dem gleichen Samen.

Andere Tipps

Die meisten wiederholbare Zufallszahlen-Generatoren müssen Zustand in irgendeiner Form. Ohne Zustand, können sie nicht tun, was als nächstes kommt. Um sicher zu fädeln, müssen Sie einen Weg auf den Zustand zu halten, sich selbst (dh, es kann nicht global sein).

Wenn Sie sagen, „muss die gleiche Folge von Zufallszahlen erzeugen“ tun Sie bedeuten, dass

  • braucht Jeder Thread einen Strom von Zahlen identisch mit dem anderen Thread zu generieren? Dies bedeutet, den Samen der Wahl vor Fäden Abziehen, dann den einen lokalen Thread-PRNG mit dem gleichen Samen in jedem Thread instanziieren.

oder

  • Sie wollen die gleiche Zahlenfolge zwischen verschiedenen Läufen der Programme in der Lage sein zu wiederholen, aber jeder Thread seine eigene unabhängige Folge erzeugt? In diesem Fall können Sie immer noch keinen einzigen PRNG teilen, weil der Faden Betriebsablauf nicht-deterministisch ist. So Samt einen einzigen PRNG mit einem bekannten Samen vor dem Start von Fäden, und verwenden Sie es die ersten Samen für die Fäden zu erzeugen. Dann Sie instanziiert lokale Thread-Generatoren in jedem Thread ...

In jedem dieser Fälle sollten Sie beachten, was Neil Butterworth sagen über die Statistik: die meisten der üblichen Garantien, dass der PRNG wie Anspruch sind nicht zuverlässig , wenn Mischströme auf diese Weise erzeugt.


In beiden Fällen müssen Sie einen lokalen Thread-PRNG. Ich weiß nicht, was in f90 verfügbar ist ... aber Sie können auch schreiben Sie besitzen (Lookup Mersenne Twister , und schreiben Sie eine routne, der die gespeicherte Zustand als Parameter ...).

In Fortran 77, würde dies so aussehen wie

      function PRNGthread (state)

      double state(statesize)

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

      PRNGthread = result
      return 

und jedes Ihrer Threads sollte einen separaten Zustandsvektor beibehalten, obwohl alle den gleichen Anfangswert verwendet werden.

Ich verstehe Sie jeden Thread müssen den gleichen Strom von Zufallszahlen erzeugen.

Ein sehr guter Pseudo Random-Generator, der einen reproduzierbaren Strom von Zahlen generieren und ist ziemlich schnell ist die MT19937 . So stellen Sie sicher, dass Sie die Samen erzeugen, bevor die Fäden Laich ab, sondern erzeugen in jedem Thread (machen die Instanz des MT Thread local) eine separate Instanz des MT. Auf diese Weise gewährleistet werden, dass jeder MT den gleichen Strom von Zahlen erzeugen.

Wie wäre es SPRNG ? Ich habe es nicht versucht, mich aber.

I codiert eine Thread-sichere Fortran 90-Version des Mersenne-Twister / MT19973. Der Zustand des PRNG wird in einem abgeleiteten Typ (randomNumberSequence) gespeichert, und Sie verwenden Verfahren des Generators auf Saatgut oder das nächste Element in der Sequenz zu erhalten.

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

Die Alternativen zu sein scheinen:

  • Verwenden Sie ein Synchronisationsobjekt (wie Ein Mutex) auf dem Keimgenerator Wert. Dies wird leider serialise Code auf Zugriffe auf Generator
  • Verwenden Sie thread-lokale Speicher in der Generator so dass jeder Faden seine eigene bekommt Samen - dies kann dazu führen, statstical Probleme für Ihre App
  • Wenn Ihre Plattform eine geeignete unterstützt Atom-Betrieb verwenden, um auf das, dass Samen (es wird wahrscheinlich jedoch nicht)

Nicht sehr ermutigend Liste, die ich kenne. Und, um es hinzuzufügen, ich habe keine Ahnung, wie einen von ihnen in Fortran zu implementieren!

Dieser Artikel https://www.cmiss.org/openCMISS/wiki/RandomNumberGenerationWithOpenMP nicht nur Link zu einer Fortran Implementierung, erwähnt aber wichtige Punkte benötigt ein PRNG verwendbar mit Fäden zu machen. Der wichtigste Punkt ist:

Die Fortran90 Version von Ziggurat hat mehrere Variablen und Arrays mit dem Attribut ‚SAVE‘. Um die einheitliche RNG, dann parallelisieren, scheint es, dass die gewünschten Änderungen dieser Variablen Arrays mit einem separaten Wert für jeden Thread zu machen, sind (Achtung Falsch Sharing). Dann, wenn die PRNG-Funktion aufgerufen wird, müssen wir die Thread-Nummer übergeben, und verwenden Sie den entsprechenden Zustandswert.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top