[英]c++ generate thread safe random numbers
我已經閱讀了一些與我所問的問題類似的問題,但答案對我來說似乎並不完整或完全清楚。
我正在嘗試並行化需要重復生成一組隨機數的參數掃描。 我目前只有一個線程做這樣的事情:
int main() {
//Get random number generators
typedef std::mt19937 MyRNG;
std::random_device rd;
//seed generator
MyRNG rng;
rng.seed(rd());
//make my uniform distributions for each parameter
std::uniform_real_distribution<> param1(-1,1);
std::uniform_real_distribution<> param2(-1,1);
double x,y;
//Do my scan
for (int i = 0; i < N; i++) {
x = param1(rng)
y = param2(rng)
//Do things with x and y*
}
這樣,每次掃描我都會得到一個新的 x 和 y。 現在我想利用多個內核並行執行此操作。 所以我轉而定義了一個 function void scan()
,它的內容與我的主要 function 基本相同。 然后我創建多個線程並讓它們運行scan()
。 但我不確定這是否是使用 std::thread 的線程安全的。 我目前在每個線程中生成的隨機數會是獨立的嗎? 我可以通過在我的void
function 之外創建我的 RNG 來節省自己的時間嗎? 謝謝。
我可能會在main
中生成種子,並將種子傳遞給每個線程 function。 我也不會直接使用std::random_device
的 output ——我會將數字放入std::set
或std::unordered_set
之類的東西中,直到我得到盡可能多的種子,以確保我沒有t 給兩個線程相同的種子(這顯然是浪費時間)。
沿着這條一般路線的東西:
int do_work(unsigned long long seed) {
//Get random number generators
typedef std::mt19937 MyRNG;
//seed generator
MyRNG rng(seed);
//make my uniform distributions for each parameter
std::uniform_real_distribution<> param1(-1,1);
std::uniform_real_distribution<> param2(-1,1);
double x,y;
//Do my scan
for (int i = 0; i < N; i++) {
x = param1(rng);
y = param2(rng);
//Do things with x and y*
}
}
static const int num_threads = 4;
int main() {
std::set<unsigned long long> seeds;
while (seeds.size() < num_threads)
seeds.insert(std::random_device()());
std::vector<std::thread> threads;
for (auto const seed: seeds)
threads.emplace_back(std::thread(do_work, seed));
for (auto &t : threads)
t.join();
}
順便說一句,使用來自random_device
的單個結果為std::mt19937
會相當多地限制生成器——你只給它 32(或可能 64)位種子,但它實際上有 19937 位種子材料. std::seed_seq
嘗試至少在一定程度上改善這一點(除其他外,您可以使用std::random_device
的多個輸出來創建種子。
哦,鑒於您的兩個uniform_real_distribution
實例使用相同的參數,可能也不需要兩個單獨的分布對象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.