当前位置: 首页 > 知识库问答 >
问题:

基于openMP线程安全随机数生成器

商运锋
2023-03-14

下面简单脚本并行产生随机数

#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相同的输出。

共有1个答案

赏育
2023-03-14

您正在与每个线程共享std::mt19937mt对象中的状态,这不是线程安全的。

或者用某种类型的锁定包装对该对象的访问,或者为每个线程[EDIT]提供一个单独的实例(可能是从您创建的mt19937的第一个实例),以便每个实例给出不同的结果[/EDIT](如果使用omp可能有任何结果的话)。

 类似资料:
  • 我需要一些帮助,用一个给定的随机数生成器用openmp并行化与蒙特卡洛方法的pi计算,这不是线程安全的。 第一:这条线对我没有帮助。 我自己的尝试是下面的#pragma omp语句。我认为I、x和y变量应该是每个线程的init,并且应该是private的。z是圆圈中所有命中数的总和,因此它应该在for循环后隐含的barriere之后求和。 认为主要的问题是随机数发生器的静态无功。我在调用函数的地方

  • 问题内容: 用例:“我忘记了密码”按钮。我们找不到用户的原始密码,因为它以散列形式存储,因此唯一要做的就是生成一个新的随机密码,然后通过电子邮件发送给他。这就要求使用密码无法预测的随机数,而mt_rand不够好,因此通常我们不能假定托管服务将提供对操作系统的访问权以安装密码随机数模块等。因此,我在寻找一种方法在PHP本身中生成安全的随机数。 到目前为止,我提出的解决方案包括存储初始种子,然后针对每

  • 问题内容: 在多个线程之间共享该类的一个实例是否有效?并特别从多个线程调用? 问题答案: 从某种意义上讲,它是线程安全的,当被多个线程使用时仍会生成随机数。 Sun / Oracle JVM实现使用同步和AtomicLong作为种子来提高线程之间的一致性。但是,文档中似乎并没有在所有平台上对此进行担保。 我不会编写要求这种保证的程序,尤其是当您无法确定调用顺序时。

  • 我正在寻找一个随机数生成器,我可以创建一个种子,并采取两个输入x和y来生成数字。每次使用相同的输入和相同的种子时,我都需要相同的数字。 我正在使用这个来随机分配一个坐标网格上的纹理,所以我需要它每次都是一样的。所以每次我在x=100,y=120的时候,在同一个种子里,我需要相同的随机数,所以相同的纹理被分配在那个点上。

  • 问题内容: PHP的函数不能提供良好的随机数。因此,我开始使用据说效果更好的产品。但是这些结果有多好?有什么方法可以再次改善它们? 我的点子: 这应该给您“完美的”随机数,不是吗? 问题答案: 伪随机数生成器(PRNG)是非常复杂的野兽。 没有真正的“完美”随机数生成器-实际上,可以通过数学函数完成的最好的操作是伪随机数-对于大多数意图和目的,它们似乎足够随机。 实际上,从PRNG返回的数字中执行

  • random 生成随机数包 文档:https://www.npmjs.com/package/random 安装:npm install --save random 封装代码: app / extend / context.js // 导入 jwt const jwt = require('jsonwebtoken') // 导入随机数包 const random = require('rando