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