Cette question est principalement liée à un problème pratique d'ingénierie logicielle, mais je serais curieux de savoir si les théoriciens pourraient fournir plus d'informations.
En termes simples, j'ai une simulation de Monte Carlo qui utilise un générateur de nombres pseudo-aléatoires, et je voudrais le paralléliser afin qu'il y ait 1000 ordinateurs exécutant la même simulation en parallèle. Par conséquent, j'ai besoin de 1000 flux indépendants de nombres pseudo-aléatoires.
Peut-on avoir 1000 flux parallèles avec les propriétés suivantes? Ici, devrait être un PRNG très connu et largement étudié avec toutes sortes de belles propriétés théoriques et empiriques.
Les flux sont prouvablement aussi bons que ce que j'obtiendrais si j'utilisais simplement et divisais le flux généré par en 1000 flux.X
Génération du numéro suivant dans un cours d' eau est (presque) aussi vite que la génération du numéro suivant avec .
Autrement dit: pouvons-nous obtenir plusieurs flux indépendants "gratuitement"?
Bien sûr, si nous utilisions simplement , en rejetant toujours 999 numéros et en choisissant 1, nous aurions certainement la propriété 1, mais nous perdrions dans le temps d'exécution par le facteur 1000.
Une idée simple serait d'utiliser 1000 copies de , avec les graines 1, 2, ..., 1000. Ce serait certainement rapide, mais ce n'est pas évident si les flux ont de bonnes propriétés statistiques.
Après quelques recherches sur Google, j'ai trouvé, par exemple, ce qui suit:
La bibliothèque SPRNG semble être conçue exactement dans ce but, et elle prend en charge plusieurs PRNG .
Le twister de Mersenne semble être un PRNG populaire de nos jours, et j'ai trouvé quelques références à une variante capable de produire plusieurs flux en parallèle.
Mais tout cela est tellement loin de mes propres domaines de recherche, que je n'ai pas pu déterminer ce qui est vraiment à la pointe de la technologie et quelles constructions fonctionnent bien non seulement en théorie mais aussi en pratique.
Quelques clarifications: je n'ai besoin d'aucune sorte de propriétés cryptographiques; c'est pour le calcul scientifique. J'aurai besoin de milliards de nombres aléatoires, afin que nous puissions oublier tout générateur avec une période de .
Edit: je ne peux pas utiliser un vrai RNG; J'ai besoin d'un PRNG déterministe. Premièrement, cela aide beaucoup au débogage et rend tout reproductible. Deuxièmement, cela me permet, par exemple, de trouver la médiane de manière très efficace en exploitant le fait que je peux utiliser le modèle multi-passes (voir cette question ).
Edit 2: Il y a une question étroitement liée @ StackOverflow: Générateur de nombres pseudo-aléatoires pour l'environnement de cluster .
la source
Réponses:
Vous pouvez utiliser une évolution de l'algorithme Mersenne Twister développé par Saito et Matsumoto:
SIMD Fast Mersenne Twister (SFMT)
SFMT est un générateur de registre à décalage à rétroaction linéaire (LFSR) qui génère un entier pseudo-aléatoire de 128 bits en une seule étape. SFMT est conçu avec le parallélisme récent des processeurs modernes, tels que le pipelining à plusieurs étapes et les instructions SIMD (par exemple entier 128 bits). Il prend en charge les entiers 32 bits et 64 bits, ainsi que la virgule flottante double précision en sortie. SFMT est beaucoup plus rapide que MT, sur la plupart des plateformes. Non seulement la vitesse, mais aussi les dimensions des équidistributions avec une précision de v-bit sont améliorées. De plus, la récupération d'un état initial de 0 excès est beaucoup plus rapide. Voir la thèse de maîtrise de Mutsuo Saito pour plus de détails .
La période varie de à 2 216091 - 1 .2607- 1 2216091- 1
L'utilisation d'un même générateur de nombres aléatoires pour générer plusieurs flux indépendants en modifiant les valeurs initiales peut provoquer un problème (avec une probabilité négligeable). Pour éviter le problème, l'utilisation de paramètres différents pour chaque génération est préférable. Cette technique est appelée création dynamique des paramètres MT.
Dans le code source SFMT, vous pouvez trouver quelques exemples d'ensembles de paramètres (de périodes variables) et un script awk pour convertir un fichier CSV en un ensemble de paramètres compilables. Il existe également un outil appelé " Création dynamique de générateurs Mersenne Twister ".
Les auteurs ont récemment développé une autre version modifiée de Mersenne Twister - Mersenne Twister pour les processeurs graphiques - conçue pour fonctionner dans les GPU et tirer parti de leurs threads d'exécution parallèle natifs. La caractéristique clé est la vitesse: entiers aléatoires toutes les 4,6 ms sur une GeForce GTX 260.5 × 10sept
Les périodes de séquence générées sont , 2 23209 - 1 et 2 44497 - 1 pour la version 32 bits, et 2 23209 - 1 , 2 44497 - 1 , 2 110503 - 1 pour la version 64 bits. Il prend en charge 128 ensembles de paramètres pour chaque période, en d'autres termes, il peut générer 128 séquences de nombres pseudo-aléatoires indépendants pour chaque période. Nous avons développé Dynamic Creator pour MTGP, qui génère plus de jeux de paramètres211213- 1 223209- 1 244497- 1 223209- 1 244497- 1 2110503- 1
En effet, ils fournissent un outil MTGPDC pour créer jusqu'à jeux de paramètres (c'est-à-dire des flux indépendants).232
L'algorithme passe les principaux tests de hasard comme Diehard et NIST.
Un article préliminaire est également disponible sur arXiv: une variante de Mersenne Twister adaptée aux processeurs graphiques
la source
Il semble y avoir de nombreuses façons de résoudre ce problème, mais une façon simple serait d'utiliser le Blum Blum Shub PRNG. Ce PRNG est défini par la relation de récurrence , où N est un semi-premier. Pour obtenir un bit aléatoire de cela, vous pouvez simplement prendre la parité de bit de x i . Ce qui est bien, c'est que puisque x i + k = x 2 k i mod N = x 2 k mod λ ( N ) iXi + 1= x2je mod N N Xje Xi + k= x2kje mod N= x2k mod λ(N)jemod N k O ( log( N)3) M y Xi + 1 , y= x2Mmod λ(N)je mod N , oùx0est votre graine. De manière pratique, cela génère exactement le même flux de nombres que si vous utilisiez un seul flux et distribuiez sa sortie à chacune des machines à son tour.X0 , y= x2y mod λ(N)0 mod N X0
Ce n'est pas le plus rapide des PRNG, cependant, il ne sera utile que si les frais généraux de tout ce que vous faites dans la simulation sont nettement supérieurs au coût du PRNG. Cependant, il convient de noter qu'il sera beaucoup plus rapide pour certaines combinaisons de et N que pour d'autres, en particulier si la représentation binaire de 2 M mod λ ( N ) contient quelques 1 ou est petite.M N 2M mod λ(N)
la source
la source
Cela vous donnera un RNG cryptographique sur chaque processus, mais il n'a pas nécessairement un coût de performance. AES est rapide si vous avez du matériel qui le prend en charge, et ChaCha est rapide malgré tout. Bien sûr, vous voudrez certainement mesurer cela dans votre environnement spécifique.
la source
Il existe maintenant une fonction de saut pour SFMT (une implémentation rapide de Mersenne Twister).
Cela me permet d'initialiser 1000 MT afin qu'il n'y ait pas de chevauchement de cycle. Et SFMT devrait être plus rapide que MTGP. Presque parfait pour mes besoins.
la source
Vous pouvez simplement utiliser 1000 instances de Mersenne Twister initialisées avec différentes graines.
Vous pouvez échantillonner les graines d'un autre Twister Mersenne, ou, pour être plus sûr de leur indépendance, du générateur de nombres pseudo-aléatoires du système d'exploitation (/ dev / urandom sous Linux).
Le Mersenne Twister fonctionne toujours sur la même séquence cyclique, la graine contrôle l'endroit où vous commencez à le générer. Avec des graines échantillonnées indépendamment, chaque générateur démarrera à des points différents, généralement très éloignés, avec une très faible probabilité d'intersection.
la source