verwenden lässt, verwende ich die neuen Zufallszahlengeneratoren in C++ 11. Obwohl es unterschiedliche Meinungen gibt, scheint es, dass die Mehrheit der Meinung ist, dass sie nicht threadsicher sind. Als Konsequenz möchte ich ein Programm erstellen, bei dem jeder Thread seinen eigenen RNG verwendet.Wie man jeden Thread seinen eigenen RNG in C++ 11
Ein Beispiel ist in der damit verbundenen Diskussion gegeben, wie dies mit OpenMP zu erreichen:
#include <random>
#include <iostream>
#include <time.h>
#include "omp.h"
using namespace std;
int main()
{
unsigned long long app = 0;
{
//mt19937_64 engine((omp_get_thread_num() + 1)); //USE FOR MULTITHREADING
mt19937_64 engine; //USE FOR SINGLE THREAD
uniform_real_distribution<double> zeroToOne(0.0, 1.0);
//#pragma omp parallel for reduction(+:app) //USE FOR MULTITHREADING
for (unsigned long long i = 0; i < 2000000000; i++)
{
if(zeroToOne(engine) < 0.5) app++;
}
}
cout << app << endl;
return 0;
}
Wenn ich die Multi-Threaded-und Single-Threaded-Version dieses Programm ausführen und verfolgen die Zeit, sie nehmen Sie die gleiche Zeit, um nach der Ausführung zu beenden. Auch app
hat nicht die gleiche Größe in den beiden Fällen, aber ich vermute, dass nur wegen der verschiedenen Samen ist.
Frage: Zeigt das angegebene Beispiel korrekt, wie jeder Thread seinen eigenen RNG verwendet? Wenn nicht, kann ich ein Beispiel dafür sehen oder einen Verweis auf einen Ort bekommen, an dem sie erklären, wie dies zu erreichen ist?
Sie vorschlagen, für dieses Beispiel danken, die sehr hilfreich ist. Ich habe zwei Fragen: (1) Darf ich fragen, warum Sie sich für ': engines()' entschieden haben? Streng genommen, ist das erforderlich? .... (2) Darf ich das Objekt 'rand' in einer späteren Schleife in meinem Programm verwenden, das nicht parallelisiert ist? – BillyJean
@BillyJean (1) Nicht erforderlich, aber mein persönlicher Stil, um jedes Element ctor in der Initialisierungsliste aufzurufen, wenn mindestens einer aufgerufen wird. (2) Nicht 100% sicher, aber ich denke 'omp_get_thread_num()' gibt 0 für nicht parallelisierte Region zurück, also Ja. – hansmaad
Eine letzte Frage: Sagen wir, ich mache 'RNG' global und ihr Objekt' rand' global. Statt der Bedingung '(rand() <0.5) 'rufe ich jetzt eine globale Funktion' func' auf, die einige Berechnungen durchführt, die von 'rand' abhängen. Wird die Verwendung von 'rand' in' func' immer noch threadsicher sein? Ich würde "ja" sagen, aber ich würde gerne Ihre Meinung hören. – BillyJean