Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用OpenMP以线程安全的方式生成随机数_C++_Multithreading_Random_Openmp - Fatal编程技术网

C++ 如何使用OpenMP以线程安全的方式生成随机数

C++ 如何使用OpenMP以线程安全的方式生成随机数,c++,multithreading,random,openmp,C++,Multithreading,Random,Openmp,在并行化之前,我在循环外创建了一个default\u random\u engine对象,因为创建这样的对象并不便宜。我在循环中重复使用它 当与OpenMP并行时,我注意到uniform\u dist(engine)对随机引擎进行可变引用,我认为随机引擎不是线程安全的。 程序没有崩溃,但我担心它的正确性 我假设random\u device是线程安全的,因此我可以将default\u random\u engine的定义移动到循环中,但我不想每次迭代都创建一个随机引擎对象,因为我读到了这一点并不

在并行化之前,我在循环外创建了一个
default\u random\u engine
对象,因为创建这样的对象并不便宜。我在循环中重复使用它

当与
OpenMP
并行时,我注意到
uniform\u dist(engine)
对随机引擎进行可变引用,我认为随机引擎不是线程安全的。 程序没有崩溃,但我担心它的正确性

我假设
random\u device
是线程安全的,因此我可以将
default\u random\u engine
的定义移动到循环中,但我不想每次迭代都创建一个随机引擎对象,因为我读到了这一点并不便宜

我认为另一种方法是创建
default\u random\u engine
对象的数组(大小:线程数),并在每次迭代开始时根据线程ID使用OpenMP函数选择正确的对象

有更好的办法吗

#include <iostream>
#include <random>
using namespace std;

int main() {
    int N = 1000;
    vector<int> v(N);
    random_device r;
    default_random_engine engine(r());

    #pragma omp parallel for
    for (int i = 0; i < N; ++i) {
         uniform_int_distribution<int> uniform_dist(1, 100);
         // Perform heavy calculations
         v[i] = uniform_dist(engine); // I assume this is thread unsafe
    }
    return 0;
}
#包括
#包括
使用名称空间std;
int main(){
int N=1000;
向量v(N);
随机_装置r;
默认的随机引擎(r());
#pragma-omp并行
对于(int i=0;i
由于实际代码将随机引擎传递给许多函数(每个函数从不同的分布生成整数和实数),因此我选择了每个线程的生成器数组,因为它对代码库的更改最少:

#include <iostream>
#include <omp.h>
#include <vector>
#include <random>
using namespace std;

int main() {
    random_device r;
    std::vector<std::default_random_engine> generators;
    for (int i = 0, N = omp_get_max_threads(); i < N; ++i) {
        generators.emplace_back(default_random_engine(r()));
    }

    int N = 1000;
    vector<int> v(N);

    #pragma omp parallel for
    for (int i = 0; i < N; ++i) {
        // Get the generator based on thread id
        default_random_engine& engine = generators[omp_get_thread_num()];
        // Perform heavy calculations
        uniform_int_distribution<int> uniform_dist(1, 100);
        v[i] = uniform_dist(engine); // I assume this is thread unsafe
    }
    return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
int main(){
随机_装置r;
向量发生器;
对于(int i=0,N=omp_get_max_threads();i
请记住,此代码假定程序中从未调用函数
omp\u set\u num\u threads
。如果发生这种情况,线程将可能获得比旧的
omp\u get\u thread\u num()
更大的编号(
omp\u get\u thread\u num()
),这将导致缓冲区溢出错误


不幸的是,此解决方案假定了标准不要求的实现细节。

是的,每个线程都需要一个单独的生成器实例。请查看幻灯片132。。。查看xoroshiro128+()