簡體   English   中英

std::random_device 的線程安全

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM