2014-06-24 66 views
0

我正在使用Intel TBB,其中每個線程都調用一個const函數對象。的代碼如下在Intel TBB函數對象(相同種子/不同種子)中生成線程安全隨機數

#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)​​
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()
我怎麼做,要使用一個線程安全的隨機數?我的隨機數生成器類對象必須包含常量 功能,否則我得到的編譯錯誤,因爲TBB限制了函數對象 應包含運營商()()爲const ...

因此,在短期我的問題有以下幾種:
1)在TBB中使用線程安全的隨機數發生器。上述的隨機數 發電機可以提高效率嗎?
2)我可以使它靜態(相同的種子),但線程安全嗎?如果是這樣,我只需要一些想法, 我可以自己實現它。
3)在tbb :: parallel_for_each()使用線程安全隨機數發生器的任何想法()
4)在這種情況下,我可以以某種方式使用boost variate generator嗎?在統一的Real類中定義引擎和分配並將它們組合以獲得一個生成器()對象

如果有任何不清楚的地方,請讓我知道我會澄清相同的。

+1

它不是線程安全的,因爲'erand48()'不 - 給每個線程都有自己的私人'xsubi'或者其他東西,並且不要每次都初始化發生器! – loreb

回答

0
  1. 您可以使用庫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

相關問題