Ich hatte Probleme bei der Generierung von Zufallszahlen über mehrere Threads. Dies war der Grund für die Verwendung der gleichen Random-Engine für alle Threads. Dann habe ich einen Vektor implementiert, der für jeden Thread eine zufällige Engine enthält (fand diese Lösung in einem anderen Post hier im Stackoverflow). Aber ich würde erwarten, dass die Anzahl der Iterationen pro Sekunde linear mit der Anzahl der Threads wächst, die ich ausführe. Aber das scheint nicht der Fall zu sein.Engpass bei der Zufallsgenerierung mit mehreren Threads
Hier ist ein minimales Beispiel:
#include <random>
#include <omp.h>
const int threads = 4;
int main()
{
std::uniform_int_distribution<uint64_t> uint_dist;
std::vector<std::mt19937_64> random_engines;
std::random_device rd;
for (int i = 0;i < threads;i++)
random_engines.push_back(std::mt19937_64((rd())));
omp_set_num_threads(threads);
int counter = 0;
#pragma omp parallel for
for (int i = 0;i < threads;++i)
{
int thread = omp_get_thread_num();
while (counter < 100)
{
if (uint_dist((random_engines[thread])) < (1ULL << 42))
counter++;
}
}
}
Während diesen Code mit einem aktiven Thread ausgeführt wird es eine durchschnittliche Ausführungszeit von ca. 4 Sekunden auf meiner CPU nimmt. Wenn ich Threads auf 4 setze, ergibt sich eine durchschnittliche Ausführungszeit von ~ 2 Sekunden, also erhält die Anzahl der Threads einen Multiplikator von 4, was zu einer Beschleunigung von 2 führt. Vermisse ich etwas?
Es gibt ein mögliches Problem mit der Synchronisierung für 'Counter': entweder Threads blockieren einander, oder lesen-ändern-schreiben ist nicht atomar und einige Schreibvorgänge sind routinemäßig verloren. Ich kenne OpenMP nicht genug, um zu sagen, was wahrscheinlicher ist. –