2013-04-13 95 views
4

我正在使用由C++ 11提供的RNG,並且我也在使用OpenMP。我已經爲每個線程分配了一個引擎,並且作爲測試,我將相同的種子分配給每個引擎。這意味着我希望兩個線程都能產生完全相同的隨機生成數字序列。這裏是一個MWE:使用相同的引擎並行生成隨機數

#include <iostream> 
#include <random> 

using namespace std; 


uniform_real_distribution<double> uni(0, 1); 
normal_distribution<double> nor(0, 1); 


int main() 
{ 
    #pragma omp parallel 
    { 
     mt19937 eng(0); //GIVE EACH THREAD ITS OWN ENGINE 
     vector<double> vec; 

     #pragma omp for 
     for(int i=0; i<5; i++) 
     { 
      nor(eng); 
      vec.push_back(uni(eng)); 
     } 
     #pragma omp critical 
     cout << vec[0] << endl; 
    } 



    return 0; 
} 

大多數情況下,我得到的輸出0.857946 0.857946,但幾次我得到0.857946 0.592845。當兩個線程具有相同的,不相關的引擎時,後者的結果如何?

+0

評論:它似乎只出現在我包括'也沒有(英);'...不是說它更有意義.. – BillyJean

回答

6

您還必須在omp parallel區域內放入noruni。像這樣:

#pragma omp parallel 
{ 
    uniform_real_distribution<double> uni(0, 1); 
    normal_distribution<double> nor(0, 1); 
    mt19937 eng(0); //GIVE EACH THREAD ITS OWN ENGINE 
    vector<double> vec; 

否則每個線程只有一個副本,實際上每個線程都需要自己的副本。

更新補充:我現在看到完全相同的問題在 this stackoverflow thread討論。

+0

我不認爲問題應該被標記爲重複時,當他們的答案是相同的;一個答案適用於多個問題是有道理的,但由於問題本身不同,因此將它們標記爲重複沒有多大意義。 –

+0

@凱爾:好的,我已經編輯了我的答案。 – TonyK

+0

我明白了。但是這個解決方案看起來非常僵化,因爲我必須在我的程序的每個並行化區域中定義一個分佈和引擎。假設我想在'for'循環中調用一個函數,該函數用該引擎和分佈生成數字:那麼我將不得不通過引用傳遞分佈*和*引擎?即,函數的原型必須讀取'double gen_num(uniform_real_distribution &uni,mt19937&gen)'?對, – BillyJean