C++ std::random_设备的线程安全
我有一些代码看起来有点像这样:C++ std::random_设备的线程安全,c++,c++11,random,openmp,C++,C++11,Random,Openmp,我有一些代码看起来有点像这样: std::random_device rd; #pragma omp parallel { std::mt19937 gen(rd()); #pragma omp for for(int i=0; i < N; i++) { /* Do stuff with random numbers from gen() */ } } std::随机设备rd; #pragma-omp并行 { 标准:mt1993
std::random_device rd;
#pragma omp parallel
{
std::mt19937 gen(rd());
#pragma omp for
for(int i=0; i < N; i++)
{
/* Do stuff with random numbers from gen() */
}
}
std::随机设备rd;
#pragma-omp并行
{
标准:mt19937 gen(rd());
#pragma omp for
对于(int i=0;i
我有几个问题:
std::random\u设备是否线程安全?i、 当几个线程同时调用它时,它会做一些没有帮助的事情吗
- 这通常是个好主意吗?我应该担心重叠的随机数流吗李>
- 有没有更好的方法来实现我想要的(每个线程中独立的随机数流-我现在不太担心再现性)李>
如果它对std::random_设备的工作有任何影响,我主要在Windows上运行,尽管我希望代码在Linux和OSX上也同样有效。并行使用random设备不是一个好主意。即使是阻塞,您可能不会遇到重叠随机数流的问题,但您会添加一个额外的同步点 您应该设置尽可能多的随机数引擎(RNE)以启动尽可能多的线程,
omp\u get\u num\u threads()
。
创建RNE的std::vector,并在程序的顺序部分中对其进行种子设定。对于种子设定,可以使用随机设备和
然后在每个线程中使用与线程编号关联的RNE,omp\u get\u thread\u num()
永远不要使用随机设备生成随机数,它的速度很慢,而且通常不会生成均匀分布的随机数
根据所需随机数的质量,可以使用预定义的随机数生成器之一。如果你在做蒙特卡罗模拟或密码学,要特别小心你选择的算法
你会在网站上找到很多关于随机引擎的有用信息
.在没有WinRT的Windows上,它使用
CryptGenRandom
,这是线程安全的
在使用WinRT的Windows上,它使用加密缓冲区::GeneratorDOM
。没有关于此线程安全性的文档,但它似乎没有状态。因此,它应该是线程安全的
在Linux上,它似乎是从线程安全的/dev/uradom
读取的
我从libs/random/src/random\u device.cpp
中阅读了这个实现
我不知道该文件中的
\uCXXRT\uSTD\uName
是什么,谷歌搜索该文件会生成boost::random\u设备作为唯一的结果。也许没什么 您可以实现再现性,但使用特定种子而不是使用std::random_设备
random_设备
可能会阻塞。如果您想要的是并行性,那么这样使用它没有多大意义。您可以使用带有random\u device
的全局PRNG来为mt19937
进行种子设定(但需要显式锁定)。另请参阅,您可能需要使用omp\u get\u max\u threads()
实际查询线程数。当并行上下文用完时,omp\u get\u num\u threads()
将始终返回1。