我正在使用英特尔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)在这种情况下,我可以以某种方式使用boost variate generator吗?在统一的Real类中定义引擎和分布,并将它们组合起来得到一个generator()对象
如果有任何不明确的地方,请告诉我,我会澄清同样的事情。
答案 0 :(得分:0)
您可以使用库Boost.Random http://www.boost.org/doc/libs/1_55_0/doc/html/boost_random.html来获取线程安全的可复制随机数生成器。
你的代码已经存在这个常量问题(operator()应该是const而不是事实上的)。一个以标准C ++方式解决它:一些成员被声明为mutable
。你在班级class uniformReal
中做了这个,使用Boost.Random,你可以将整个生成器声明为mutable