I am using Intel TBB where each thread calls a const function object. the code is as follows
#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));
Program Flow is explained as below:
(assume 8 threads and 8 vertex in parallel --> assume)
1) tbb::parallel_for_each(vertex_begin, vertex_end, my_func<Graph, int>(G, t));
2) each thread calls my_func. Inside my_func, each thread computes a an out_edge_iterator range for the vertex.
3) each thread does the following: process_edge function object for each edge:
std::for_each(out_edge_begin, out_edge_end, process_edge<graph>(G))
;
4) the function object process_edge has a random number generator (0,1) As above.
My questions is:
Is the random number generator thread safe? Because I sometimes get erroneous results. Although the answer is depending upon the random number generated
I am not sure my random number generator class is thread safe or not.
Suppose I want to use the same seed so that same random number is generated.
How do I achieve that?
I get a bit confused in generating thread safe random number generator class
If suppose I want to use a thread safe random number in tbb::parallel_for_each()
how do i do that? My random number generator class object must contain const
functions, else I get compiler error because of TBB restricts that function object
should contain the operator()() as const ...
So in short my questions are the following:
1) using thread safe random number generator in TBB. Can the above random number
generator be made more efficient ?
2) can I make it static (same seed) but thread safe ? If so I just need some idea,
I can implement it on my own.
3) any ideas to use thread safe random number generator in tbb::parallel_for_each()
4) Can I somehow use boost variate generator in this case? define engine and distribution in the uniform Real class and combine them to get a generator() object
If anything is not clear, please let me know I will clarify the same.