Zufallszahlen für mehrere Threads

Problem

Ich beabsichtige, eine C ++ 11-Anwendung für Linux zu schreiben, die eine numerische Simulation (keine Kryptographie) auf der Basis von ungefähr einer Million pseudozufälliger 32-Bit-Zahlen ausführt. Zur Beschleunigung möchte ich die Simulation in parallelen Threads mit allen Kernen einer Desktop-CPU durchführen. Ich würde gerne den Mersenne Twister benutzenmt19937 bereitgestellt von Boost als PRNG, und ich denke, aus Leistungsgründen sollte ich einen solchen PRNG pro Thread haben. Jetzt bin ich mir nicht sicher, wie ich sie setzen soll, um zu vermeiden, dass dieselbe Folge von Zufallszahlen in mehreren Threads erzeugt wird.

Alternativen

Hier sind die Alternativen, an die ich bisher gedacht habe:

Setzen Sie den PRNG für jeden Thread unabhängig von/dev/urandom.

Ich bin etwas besorgt über den Fall, dass der Systementropiepool erschöpft ist, da ich nicht weiß, wie der systeminterne PRNG funktioniert. Könnte es passieren, dass ich versehentlich aufeinanderfolgende Samen erhalte, die genau aufeinanderfolgende Zustände des Mersenne Twister identifizieren, weil/dev/urandom verwendet ein Mersenne Twister selbst? Wahrscheinlich stark mit meinen Sorgen um den nächsten Punkt verbunden.

Einen PRNG von säen/dev/urandom und die anderen von diesem ersten.

Grundsätzlich das gleiche Problem: Ist es gut oder schlecht, ein PRNG zu verwenden, um ein anderes zu generieren, das denselben Algorithmus verwendet? Oder mit anderen Worten, liest 625 32-Bit-Ganzzahlen von amt19937 entsprechen direkt dem internen Zustand dermt19937 Generator zu irgendeinem Zeitpunkt während dieser Generation?

Setzen Sie andere zuerst mit Nicht-Mersenne-Informationen ein.

Da sich die Verwendung desselben Algorithmus zur Erzeugung von Zufallszahlen und zur Erzeugung des anfänglichen Startwerts irgendwie als eine schlechte Idee anfühlt, habe ich mir überlegt, ein Element einzuführen, das nicht vom Mersenne-Twister-Algorithmus abhängig ist. Zum Beispiel könnte ich die Thread-ID in jedes Element des anfänglichen Seed-Vektors XOR-verknüpfen. Macht das die Dinge besser?

Teilen Sie ein PRNG unter Threads.

Dies würde sicherstellen, dass es nur eine Sequenz mit allen bekannten und wünschenswerten Eigenschaften des Mersenne-Twisters gibt. Der für die Steuerung des Zugriffs auf diesen Generator erforderliche Sperraufwand bereitet mir jedoch einige Sorgen. Da ich keine gegenteiligen Beweise gefunden habe, gehe ich davon aus, dass ich als Bibliotheksbenutzer dafür verantwortlich wäre, den gleichzeitigen Zugriff auf das PRNG zu verhindern.

Generieren Sie alle Zufallszahlen vor.

Dies hätte zur Folge, dass ein Thread alle erforderlichen 1-Millionen-Zufallszahlen generiert, die später von den verschiedenen Threads verwendet werden. Der Speicherbedarf von 4M wäre im Vergleich zur Gesamtanwendung gering. Was mich bei diesem Ansatz am meisten beunruhigt, ist, dass die Erzeugung von Zufallszahlen selbst nicht gleichzeitig erfolgt. Dieser ganze Ansatz lässt sich auch nicht gut skalieren.

Fragen

Welchen dieser Ansätze würden Sie vorschlagen und warum? Oder haben Sie einen anderen Vorschlag?

Wissen Sie, welche meiner Bedenken berechtigt sind und welche nur auf meine mangelnde Einsicht in die tatsächliche Funktionsweise zurückzuführen sind?

Antworten auf die Frage(8)

Ihre Antwort auf die Frage