[英]Thread safety of std::random_device
我有一些代碼看起來有點像這樣:
std::random_device rd;
#pragma omp parallel
{
std::mt19937 gen(rd());
#pragma omp for
for(int i=0; i < N; i++)
{
/* Do stuff with random numbers from gen() */
}
}
我有幾個問題:
std::random_device
線程安全嗎? 即當多個線程同時調用它時,它會做一些無用的事情嗎? 如果它對我主要在 Windows 上運行的std::random_device
的工作有任何影響,盡管我希望代碼在 Linux 和 OSX 上也能同樣良好地工作。
並行使用隨機設備不是一個好主意。 即使它阻塞了,您也可能不會遇到重疊隨機數流的問題,但是您添加了一個額外的同步點。
您應該設置與要啟動的線程一樣多的隨機數引擎 (RNE) omp_get_num_threads()
。 創建 RNE 的 std::vector 並將它們播種到程序的順序部分。 對於播種,您可以使用隨機設備和std::seed_seq 。
然后在每個線程中使用與線程號omp_get_thread_num()
關聯的 RNE。
永遠不要使用隨機設備生成隨機數,它很慢,而且一般不會生成均勻分布的隨機數!
根據您需要的隨機數的質量,您可以使用其中一種預定義的隨機數生成器。 如果您正在進行蒙特卡羅模擬或密碼學,請格外小心您選擇的算法。
您會在https://en.cppreference.com/w/cpp/numeric/random找到很多關於隨機引擎的有用信息。
在沒有 WinRT 的 Windows 上,它使用CryptGenRandom
,這是線程安全的https://stackoverflow.com/a/46171432/2024042
在帶有 WinRT 的 Windows 上,它使用CryptographicBuffer::GenerateRandom
。 沒有關於此線程安全的文檔,但它似乎沒有狀態。 因此它應該是線程安全的。
在 Linux 上,它似乎是從/dev/urandom
讀取的,它是線程安全的。
我從libs/random/src/random_device.cpp
中讀取了這個實現。
我不知道該文件中的_CXXRT_STD_NAME
是什么,谷歌搜索會產生 boost::random_device 作為唯一結果。 也許沒什么!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.