在Intel TBB函数对象(相同种子/不同种子)中生成线程安全随机数

问题描述 投票:0回答:1

我正在使用Intel TBB,其中每个线程都调用const函数对象。代码如下

#include "process_edge.hpp"
// process a vertex in graph
template <typename Graph, typename time>
struct my_func{ 
 public:
  my_func() {  } 
  my_funct(Graph& _G, time _t) : G(_G), t(_t) { } 

  template <typename vertex_t>
  void operator()( vertex_t  vertex ) const { 

    boost::tie (boeit, eoeit) = boost::out_edges(vertex, G);  //get out_edge_iterators 
    for_each(boeit, eoeit, process_edge<Graph>(G)); //for each out_edge_iterator ---> process_edge functor  

  }
 private: 
   Graph& G;
   time t;
 };


  //process_edge.hpp file
  //process edge function object uses a random number generator (uniform real (0,1)

  #include "unif_real.hpp"  // uniform random generator class (see below)

  template <tyepname Graph>
  struct process_edge{
   public:
    process_edge() { }
    process_edge(Graph& _G) : G(_G), rnd(0,1) {  }

   template <typename edge_t>
   void operator() (edge_t edge) const { 

    if(rnd().generate() > 0.5)
       //do something with edge
  } 
 private
  Graph& G;
  uniformReal rnd;
 };


 //uniformReal.hpp  //random number generator class 
class uniformReal {
 public:
   uniformReal (int a, int b)
     :  range(a,b)
     {
       initialize();
      }

  void initialize() const {
    struct timeval t;
    gettimeofday(&t, 0);
    xsubi[0] = time(0);
    xsubi[1] = t.tv_usec ^ t.tv_sec;
    xsubi[2] = t.tv_usec ^ t.tv_sec * time(0);
  }


   inline double generate() const {
     initialize();
     return  erand48(xsubi);
   }

  private:
   mutable unsigned short int xsubi[3];
  };




 //call the parallel_for_each for vertex 
 tbb::parallel_for_each(vertex_begin, vertex_end, my_func<Graph,int>(G, t));

程序流程解释如下:(假设8个线程和8个顶点并行->假设)1)tbb::parallel_for_each(vertex_begin, vertex_end, my_func<Graph, int>(G, t));2)每个线程都调用my_func。在my_func内部,每个线程都会为顶点计算一个out_edge_iterator范围。3)每个线程执行以下操作:每个边缘的process_edge函数对象:std::for_each(out_edge_begin, out_edge_end, process_edge<graph>(G));4)函数对象process_edge具有如上所述的随机数生成器(0,1)。

我的问题是:随机数生成器线程安全吗?因为有时我会得到错误的结果。尽管答案取决于生成的随机数我不确定我的随机数生成器类是否是线程安全的。

假设我想使用相同的种子,以便生成相同的随机数。我该如何实现?我对生成线程安全随机数生成器类感到有些困惑

如果我想在tbb::parallel_for_each()中使用线程安全随机数,我怎么做?我的随机数生成器类对象必须包含const函数,否则由于TBB限制了该函数对象而导致编译器错误应该包含operator()()作为const ...

总之,我的问题如下:1)在TBB中使用线程安全随机数生成器。可以上面随机数发电机效率更高?2)我可以使其静态(相同的种子)但线程安全吗?如果是这样,我只需要一些想法,我可以自己实现。3)在tbb :: parallel_for_each()中使用线程安全随机数生成器的任何想法4)在这种情况下,我可以以某种方式使用升压变量发生器吗?在统一的Real类中定义引擎和分布,并将它们组合在一起以生成generator()对象

如果不清楚,请让我知道,我将予以澄清。

c++ multithreading random boost tbb-flow-graph
1个回答
0
投票
  1. 您可以使用库Boost.Random http://www.boost.org/doc/libs/1_55_0/doc/html/boost_random.html获取线程安全的可复制随机数生成器。

  2. 您的代码已经存在此一致性问题(operator()应该为const,但事实上不是)。一种用标准的C ++方式解决:将某些成员声明为mutable。您是在类class uniformReal中使用Boost.Random做到的,您可以将整个生成器声明为mutable

© www.soinside.com 2019 - 2024. All rights reserved.