OpenMP und C++11 Zufallszahlengenerator
-
Klaus82 schrieb:
ich gebe jedem Thread einen eigenen (neu entworfenen) Zufallszahlengenerator. Jetzt habe ich aber nach wie vor das Problem, dass die erste und zweite Sequenz dieselben Zufallszahlen liefern.
Verwende unterschiedliche Seeds, z.B. von
std::random_device.
-
Nexus schrieb:
Klaus82 schrieb:
ich gebe jedem Thread einen eigenen (neu entworfenen) Zufallszahlengenerator. Jetzt habe ich aber nach wie vor das Problem, dass die erste und zweite Sequenz dieselben Zufallszahlen liefern.
Verwende unterschiedliche Seeds, z.B. von
std::random_device.Was es nicht alles gibt.
Na ja, am Ende würde ich damit genau das tun, was ich oben als quick and dirty bezeichnet habe: Der seed wird jedes Mal zufällig bestimmt. Was natürlich super für die Reproduzierbarkeit ist.

#ifndef RNG_H #define RNG_H #include <iostream> #include <random> #include "omp.h" using namespace std; class RNG { public: RNG(): _engine( _rd() ), _distribution( 0.0, 1.0 ){}; double operator()(){ return _distribution( _engine ); } private: random_device _rd; mt19937 _engine; uniform_real_distribution<double> _distribution; }; #endifGruß,
-- Klaus.
-
Du erzeugst deine RNGs in jedem parallel-Block aufs neue, und das mit den selben Seeds. Klar, daß immer wieder dieselben Sequenzen herauskommen. Außerdem ist der Mersenne-Twister m.W. nicht gerade billig zu konstruieren.
Wie wär's mit einem übergeordneten vector<RNG> mit threads RNGs, auf die Du dann mit
rng_vec[omp_get_thread_num()]()zugreifst?
-
Caligulaminus schrieb:
Wie wär's mit einem übergeordneten vector<RNG> mit threads RNGs, Auf die Du dann mit
rng_vec[omp_get_thread_num()]()zugreifst?Du meinst so wie in meinem Startpost wofür ich schon abgewatscht wurde?

Gruß,
-- Klaus.
-
In deinem Startpost war RNG von OMP abhängig.
-
Caligulaminus schrieb:
In deinem Startpost war RNG von OMP abhängig.
Ja.
Aber ist das jetzt nicht eine konzeptionelle Frage? Ob ich einen Vektor von RNGs habe oder einen wrapper (genannt RNG) um einen Vektor von Generatoren lege?
Das macht doch nicht viel Unterschied?
Gruß,
-- Klaus.
-
Klaus82 schrieb:
Was natürlich super für die Reproduzierbarkeit ist.

Wenn du reproduzierbare Zufallszahlen willst, dann nimm eben zuvor festgelegte Seeds. Naheliegend, oder?

P.S. Ich würde nicht jedes Mal auf den Vektor zugreifen. Übergib jedem Thread seinen eigenen, unabhängigen RNG, nachdem er entsprechend geseedet wurde. Gerade in Multithreaded-Szenarien würde alles so modular wie möglich halten und nur über sehr kleine Schnittstellen miteinander kommunizieren.
-
Ja, ja ... danke für die ganzen Vorschläge.
[piensen]
Ich befürchte nur, dass es am Ende sowieso niemanden interessiert, wie penibel ich darauf achte. D.h. ich kann eigentlich auch direkt jedes Mal mitstd::random_deviceseeden.
[/piensen]
-
So,
ich habe jetzt eine große
#pragma omp parallelUmgebung, auf dass jeder Thread seinen eigenen Kram macht und jeder vorkommende PRNG wird mittelsstd::random_deviceinitialisiert.Ist die mathematisch schändlichste Lösung, aber dafür die praktikabelste.

Gruß,
-- Klaus.
-
Klaus82 schrieb:
Ist die mathematisch schändlichste Lösung, aber dafür die praktikabelste.

Schändlich ist das nur, wenn es nicht das ist, was du möchtest. Wenn es nicht das ist, was du möchtest, warum machst du es dann so?
Wenn du auf die Reproduzierbarkeit anspielst: Erstens ist es ja wohl einfach, sich dafür eine Lösung zu denken, zweitens hat Nexus diese bereits ausdrücklich erklärt.
-
Sorry für die späte Rückmeldung.
Ich habe tatsächlich nochmal den Eintrag bei Stackoverflow gefunden, wo die Generatoren im Vektor gespeichert werden und jeder Thread auf einen Eintrag zugreift - so wie ich es im Startpost geschrieben hatte.
Also scheint das doch 'okay' zu sein, oder nicht?
Gruß,
-- Klaus.