簡體   English   中英

播種並行偽隨機數生成器的好方法是什么?

[英]What is a good way to seed parallel pseudo random number generators?

我編寫的PRNG的周期為2 ^ 64。 當我使用自旋鎖保護它不受4個線程的影響時,它的運行速度比只有一個線程時慢兩倍。 互斥鎖似乎在使事情變慢方面表現得更好。 因此,我決定為每個線程使用單獨的生成器,但是這里的問題是,當種子太近時,相同系列的隨機數將一次又一次出現在不同的線程中。 我不是100%知道這將對我的模擬有多嚴重,但是我想避免植入非常緊密的PRNG。

也許我最初的問題不太明確,無法獲得簡單的解決方案。 下面我發布了我正在使用的PRNG。 它在Diehard或FIPS之類的統計測試中表現很好,但是由於我不是該領域的專家,我真的無法證明為什么。 我需要一種方法來為4個或更多並行運行的發電機找到好的種子。 如果有2個種子,則最差的一對種子是相同的種子,因此2個線程將獲得相同的隨機數序列。 最好的一對種子將產生兩個沒有重疊部分的序列。

我看到隨着並行生成器的數量或生成的隨機數的數量或兩者都變大,找到“最佳”種子集變得越來越困難。 每個任務將至少有4個線程和至少十億個隨機數生成。

我能達到的最簡單的解決方案是定期播種。 有時我可能會得到一堆不好的種子,但是在定期播種后很快就會被更好的種子所代替。

我的問題是否有可以應用於任何PRNG的一般解決方案? 或至少我當前使用的發電機可用的東西? 如果有一個專門設計並非常適合並行隨機數生成的PRNG,則可以更改我的PRNG。

static thread_local unsigned long long n;

void seedRand(unsigned long long s)
{
  n = s;
}

unsigned genRand(void)
{
  n *= 123456789;
  n ^= n >> 3;
  n ^= n << 5;
  return n ^= n >> 7;
}

如果可以訪問密碼庫,則可以使用AES加密填充的初始種子,然后在PRNG之間分配輸出。 例如,使用帶有[seed]的64位初始種子的計數器模式 ,可以將其串聯起來,直到獲得256位的明文:

[種子] [種子] [種子] [種子]

並且您的初始化向量將是[counter] [seed](您需要一個唯一的初始化向量,但不一定是安全的初始化向量,因為沒有人試圖解密您的輸出)。 這將產生256位輸出,前64位種子第一個PRNG,后64位種子第二個PRNG,依此類推。

還有其他方法可以執行此操作,具體取決於加密庫中提供的內容,例如,您可以對初始種子進行哈希處理,或者可以生成隨機UUID,直到您有足夠的位來為所有PRNG注入種子為止。

如果有一個專門設計並非常適合並行隨機數生成的PRNG,我可以更改我的PRNG

好吧,如果您願意更改RNG,則可以使用一些生成器,這些生成器具有快速(跳過的呼叫數的對數),提前跳過(又名“跳越”)的功能。

它們通過設計保證不會重疊。 假設您的每個線程模擬需要10 ^ 9 RNG調用,並且可以在8個線程上運行,然后從單種子開始,第一個線程被跳過0,第二個線程被跳過10 ^ 9,線程號N被跳過(N-1)* 10 ^ 9。

https://github.com/Iwan-Zotow/LCG-PLE63在這里是合理的可接受的代碼(它是MCNP5 fortran代碼的重新實現),但是很可能不會通過Diehard。

http://www.pcg-random.org/稍微復雜一點(我相信它已經通過了Diehard)

兩者均基於快速求冪,F。Brown着,“任意步幅生成隨機數”,Trans。 上午。 核仁 Soc。 (1994年11月)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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