【发布时间】:2017-04-20 11:40:28
【问题描述】:
以下简单脚本并行产生随机数
#include <random>
#include <iostream>
#include <omp.h>
int main(int argc, char *argv[])
{
// Three integers are expected from the command line.
// The first integer is a random seed
// The second integer is the number of threads.
// The third integer indicates the number of random numbers to produce
// Read the seed and create the random number generator and the random distribution
int seed = std::stoi(argv[1]);
std::mt19937 mt(seed);
std::uniform_real_distribution<float> dist(0, 100);
// Read the number of threads and set it.
int nbThreads = std::stoi(argv[2]);
omp_set_num_threads(nbThreads);
// Number of random number for demonstration
int n = std::stoi(argv[3]);
// Will store the random number to print them conveniently
std::vector<float> store(n);
// produce 'n' random numbers
#pragma omp parallel for
for (int i = 0 ; i < n ; ++i)
{
store[i] = dist(mt);
}
// print the random numbers
for ( auto& rnd : store )
{
std::cout << rnd << std::endl;
}
return 0;
}
上面的脚本在使用单线程时是确定性的
./test 3 1 2
55.0798
7.07249
./test 3 1 2
55.0798
7.07249
./test 7 1 2
7.63083
22.7339
./test 7 1 2
7.63083
22.7339
但是,当使用多个线程时,它是部分随机的并且包含线程之间的相关性(这可能是一个相当大的问题)
./test 3 2 2
43.1925
43.1925
./test 3 2 2
55.0798
7.07249
./test 7 2 2
22.7339
7.63083
./test 7 2 2
7.63083
7.63083
我明白为什么我的代码不是线程安全的,但我不明白如何使它成为线程安全的。是否有可能无论线程数如何都具有确定性输出?
目标是./test 87 1 200 产生与./test 87 3 200 相同的输出(即线程数不会影响对象store)。如果这不可能,那么目标是./test 87 3 200 产生与./test 87 3 200 相同的输出。
【问题讨论】:
-
你能更清楚你想做什么吗?显然,产生一系列输出的 PRNG 只能按顺序产生这些输出。你想要什么?
-
@DavidSchwartz 我编辑了这篇文章,希望让它更清楚。我正在尝试创建一个确定性过程,该过程采用随机种子并以多线程方式生成随机数。可能吗?我不确定我的评论是否有助于您理解。您能否更具体地说明不清楚的地方?
-
线程到底在做什么?为了使结果具有确定性,必须有一个到达某个特定位置的第一个结果。然后,只有这样,才会有第二个结果。正确的?看来您既要求以精确的顺序(一个,然后是下一个,等等)做事,又要求以多线程的方式来做。
-
您只能获得每个线程的确定性输出。这是因为您无法保证每个线程生成随机数的顺序。显然,共享 PRNG 将为您提供确定性的数字序列(前提是您“破坏”线程以使其线程安全);但由于哪个线程得到哪个数字不是确定性的,所以从随机数推导的任何推导也不是确定性的。 您唯一合理的选择是为每个线程使用单独的 PRNG 实例。
-
@CraigYoung 好的,所以不可能确保
./test 87 1 200提供与./test 87 3 200相同的输出,但如果我们定义一个可以确保./test 87 3 200系统地提供相同的输出PRNG 从每个线程的主 PRNG 的值中播种。休息一下,看看 openMP 是否可以做到这一点。谢谢
标签: c++ multithreading random openmp generator