Generatori di numeri pseudocasuali paralleli


20

Questa domanda è principalmente legata a un problema pratico di ingegneria del software, ma sarei curioso di sapere se i teorici potrebbero fornire maggiori informazioni in merito.


In parole povere, ho una simulazione Monte Carlo che utilizza un generatore di numeri pseudocasuali e vorrei parallelizzarlo in modo che ci siano 1000 computer che eseguono la stessa simulazione in parallelo. Pertanto ho bisogno di 1000 flussi indipendenti di numeri pseudocasuali.

Possiamo avere 1000 flussi paralleli con le seguenti proprietà? Qui X dovrebbe essere un PRNG molto noto e ampiamente studiato con tutti i tipi di belle proprietà teoriche ed empiriche.

  1. I flussi sono altrettanto buoni di quelli che otterrei se semplicemente usassi X e divido il flusso generato da X in 1000 flussi.

  2. Generando il numero successivo in qualsiasi flusso è (quasi) veloce come generare il numero successivo con X .

In altre parole: possiamo ottenere più flussi indipendenti "gratis"?

Naturalmente se usassimo semplicemente X , scartando sempre 999 numeri e selezionando 1, avremmo sicuramente la proprietà 1, ma perderemmo il tempo di esecuzione per fattore 1000.

Una semplice idea sarebbe quella di usare 1000 copie di X , con i semi 1, 2, ..., 1000. Questo sarebbe certamente veloce, ma non è ovvio se i flussi hanno buone proprietà statistiche.


Dopo alcuni googling, ho trovato, ad esempio, quanto segue:

  • La libreria SPRNG sembra essere progettata esattamente per questo scopo e supporta più PRNG .

  • Il twister di Mersenne sembra essere un PRNG popolare al giorno d'oggi, e ho trovato alcuni riferimenti a una variante che è in grado di produrre più flussi in parallelo.

Ma tutto ciò è così lontano dalle mie aree di ricerca, che non sono riuscito a capire quale sia realmente lo stato dell'arte e quali costruzioni funzionino bene non solo in teoria ma anche in pratica.


Alcuni chiarimenti: non ho bisogno di alcun tipo di proprietà crittografiche; questo è per il calcolo scientifico. Avrò bisogno di miliardi di numeri casuali, quindi possiamo dimenticare qualsiasi generatore con un periodo <232 .

Modifica: non riesco a usare un vero RNG; Ho bisogno di un PRNG deterministico. In primo luogo, aiuta molto con il debug e rende tutto ripetibile. In secondo luogo, mi permette di fare, ad esempio, la ricerca mediana in modo molto efficiente sfruttando il fatto che posso usare il modello multi-pass (vedi questa domanda ).

Modifica 2: C'è una domanda strettamente correlata @ StackOverflow: generatore di numeri pseudo-casuali per l'ambiente cluster .


6
perché non dovresti usare il PRNG con semi campionati indipendentemente? non capisco come questo non soddisfi 1 e 2, dal momento che non è necessario alcun coordinamento tra le diverse macchine1000
Sasho Nikolov,

Non sono un esperto, ma di recente (alla ricerca di informazioni su una domanda TCS) ho trovato questo hardware: idquantique.com/true-random-number-generator/… ... una scheda PCI che può generare un flusso di 16 Mb / sec di bit (quantici) casuali. ... puoi comprarne un sacco e implementare alcuni server generatori di numeri casuali ... non un ottimo approccio teorico ma i bit sono garantiti per essere "buoni" :-) :-)
Marzio De Biasi

@Vor: vorrei mantenere tutto ripetibile e deterministico. Dato un seme fisso, voglio ottenere esattamente lo stesso risultato se rieseguo l'esperimento. E voglio essere in grado di eseguire lo stesso esperimento su una singola macchina e ottenere di nuovo gli stessi risultati. (Per uno, aiuta molto quando si
esegue il

@Jukka: ok! ... e suppongo che la memorizzazione di miliardi di bit selvatici inattaccabili insieme ai risultati dell'esperimento non sia così fattibile :-) ... è necessario un esperto PRNG!
Marzio De Biasi,

2
Grazie per le risposte finora! Vediamo se otteniamo più partecipazione con una taglia ...
Jukka Suomela,

Risposte:


7

Puoi utilizzare un'evoluzione dell'algoritmo di Mersenne Twister sviluppato da Saito e Matsumoto:

Fast Mersenne Twister (SFMT) orientato al SIMD

SFMT è un generatore di Linear Feedbacked Shift Register (LFSR) che genera un intero pseudocasuale a 128 bit in un solo passaggio. SFMT è progettato con il recente parallelismo di CPU moderne, come pipeline multistadio e istruzioni SIMD (es. Intero a 128 bit). Supporta numeri interi a 32 e 64 bit, nonché in virgola mobile a precisione doppia come output. SFMT è molto più veloce di MT, nella maggior parte delle piattaforme. Non solo la velocità, ma anche le dimensioni delle equidistribuzioni con precisione v-bit sono migliorate. Inoltre, il recupero dallo stato iniziale in eccesso di 0 è molto più veloce. Vedi la tesi di Master di Mutsuo Saito per i dettagli .

Il periodo varia da a 2 216091 - 1 .2607-12216.091-1

L'uso di uno stesso generatore di numeri casuale per generare più flussi indipendenti modificando i valori iniziali può causare un problema (con probabilità trascurabilmente piccole). Per evitare il problema, è preferibile utilizzare parametri diversi per ogni generazione. Questa tecnica è chiamata creazione dinamica dei parametri MT.

Nel codice sorgente SFMT puoi trovare alcuni esempi di set di parametri (di periodi variabili) e uno script awk per convertire un file CSV in un set di parametri compilabile. Esiste anche uno strumento chiamato " Creazione dinamica di generatori Twister di Mersenne ".

Gli autori hanno recentemente sviluppato un'altra versione modificata di Mersenne Twister - Mersenne Twister per processori grafici - progettata per funzionare in GPU e sfruttare i thread di esecuzione paralleli nativi. La caratteristica chiave è la velocità: numeri interi casuali ogni 4.6ms su una GeForce GTX 260.5×107

I periodi della sequenza generata sono , 2 23209 - 1 e 2 44497 - 1 per la versione a 32 bit e 2 23209 - 1 , 2 44497 - 1 , 2 110503 - 1 per la versione a 64 bit. Supporta 128 set di parametri per ogni periodo, in altre parole, può generare 128 sequenze di numeri pseudocasuali indipendenti per ogni periodo. Abbiamo sviluppato Dynamic Creator per MTGP, che genera più set di parametri2112131223209124449712232091244497121105031

Infatti forniscono uno strumento MTGPDC per creare fino a set di parametri (ovvero flussi indipendenti).232

L'algoritmo supera i principali test di casualità come Diehard e NIST.

Un articolo preliminare è disponibile anche su arXiv: una variante di Mersenne Twister adatta per processori grafici


Uno strumento correlato ma più vecchio è Matsumoto e Nishimura (1998): Creazione dinamica di generatori di numeri pseudocasuali . Ma non sono stato in grado di capire quali di questi strumenti sono solo una prova di concetto e quali sono pacchetti software ampiamente utilizzati per la forza del settore.
Jukka Suomela,

@Jukka: forse puoi chiederlo direttamente agli autori dell'algoritmo MTGP. Dal loro sito: "... Qualsiasi feedback è il benvenuto (inviare un'e-mail a Mutsuo Saito, saito" al cartello "math.sci.hiroshima-u.ac.jp e m-mat" al cartello "math.sci.hiroshima- u.ac.jp) ... ". Forse potrebbero non essere imparziali al 100%, ma sicuramente conoscono bene i punti di forza e di debolezza di MTGP e possono dirti se può essere adatto ai tuoi scopi.
Marzio De Biasi,

Sembra che Mersenne Twister + Dynamic Creation sia il modo consigliato per farlo in Mathematica.
Jukka Suomela,

@Jukka: il pacchetto MT + DC è disponibile anche sul sito di Matsumoto ( math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html ); e penso che MTGP sia solo una variante adatta alle GPU. Quindi MT + DC sembra una scelta migliore (e testata / stabile) (a meno che non siano assolutamente necessari numeri interi casuali ogni 4,6 ms su ogni flusso :-))))5×107
Marzio De Biasi

@Vor: Se modifichi la tua risposta e sostituisci MTGP con dcmt , posso accettarla.
Jukka Suomela,

12

Sembra che ci siano molti modi per affrontare questo problema, ma un modo semplice sarebbe usare il PRNG Blum Blum Shub . Questo PRNG è definito dalla relazione di ricorrenza , dove N è un semiprime. Per ottenere un bit casuale da questo, puoi semplicemente prendere la parità di bit di x i . La cosa bella di questo è che poiché x i + k = x 2 k i  mod  N = x 2 k  mod  λ ( N ) ixi+1=xi2 mod NNxi puoi calcolare direttamente qualsiasi costante di tempo in k (cioè O ( log ( N ) 3 ) o più veloce a seconda dell'algoritmo di moltiplicazione che usi per l'esponenziale modulare). Quindi haimacchine M , quindi per la macchina indicizzata da y puoi usare il generatore x i + 1 , y = x 2 M mod  λ ( N ) i  mod  N , dove x 0 , y = xxi+k=xi2k mod N=xi2k mod λ(N)mod NkO(log(N)3)Myxi+1,y=xi2Mmod λ(N) mod N, dovex0è il tuo seme. Convenientemente, questo genera esattamente lo stesso flusso di numeri come se si utilizzasse un singolo flusso e si distribuisse a sua volta l'output a ciascuna macchina.x0,y=x02y mod λ(N) mod Nx0

Questo non è il più veloce dei PRNG, quindi sarà utile solo se il sovraccarico di qualsiasi cosa tu stia facendo nella simulazione è significativamente maggiore del costo del PRNG. Tuttavia, vale la pena sottolineare che sarà molto più veloce per alcune combinazioni di e N rispetto ad altre, in particolare se la rappresentazione binaria di 2 M  mod  λ ( N ) contiene pochi 1s o è piccola.MN2M mod λ(N)


1
Penso che sarebbe più veloce lasciare che ogni macchina generi una porzione contigua della sequenza, spaziandoli così lontano da non intersecarsi. Comunque, usare Blum Blum Shub per applicazioni non crittografiche mi sembra un po 'eccessivo.
Antonio Valerio Miceli-Barone,

1
@Antonio: Sì, sarebbe leggermente più veloce, soprattutto se sai in anticipo esattamente quante prove hai bisogno. Se non lo sai, penso che otterrai lo stesso ridimensionamento in entrambi i modi. Wierdly Blum Blum Shub era esattamente il PRNG che ci hanno insegnato anni fa nella fisica computazionale. Se non lo si utilizza per scopi crittografici, è possibile utilizzare un modulo molto più piccolo, quindi non è poi così lento, e per molte attività sarà veloce rispetto a qualsiasi funzione della variabile casuale che è necessario calcolare.
Joe Fitzsimons,

5

Che ne dici di una fase di preelaborazione? Dato un seme casuale (di dimensione n ), esegui X per ottenere un flusso pseudocasuale di dimensione 1000 n . Indica questo flusso con s 1 , s 2 , , s 1000 , dove per 1 i 1000 , s i è una porzione contigua del flusso di dimensione n .snX1000ns1,s2,,s10001i1000sin

Questa fase di preelaborazione può essere eseguita con un overhead molto basso, dato che è un PRNG efficiente (oggi abbiamo PRNG molto veloci).X

Ora, dare come il seme al I ° macchina, che utilizza X per generare il proprio flusso pseudo-casuale.siiX

Date le belle proprietà di , a meno che non sia noto, per ogni 1 i < j 1000 , i semi s i e s j sono indipendenti dal punto di vista computazionale. Inoltre, si ha solo per generare e salvare un piccolo seme (cioè s ); pertanto, questo approccio non richiede molta casualità o archiviazione.Xs1i<j1000sisjs


Non è essenzialmente lo stesso approccio suggerito da @Antonio: usare un PRNG per generare semi per se stesso. Ho un po 'di inquietudine a riguardo ... Per dare un banale esempio di cosa potrebbe andare storto, considera un PRNG dove output = stato interno e il seme semplicemente imposta lo stato interno.
Jukka Suomela,

@Jukka: Il mio approccio è simile a quello di Antonio, ma il mio è più generale. Il PRNG nel tuo esempio (dove output = stato interno) non sembra essere crittograficamente sicuro. Un PRNG è crittograficamente sicuro se il suo output non è distinguibile dal punto di vista computazionale dalla distribuzione uniforme. Vedi questo per maggiori informazioni. PS: Il PRNG Blum-Blum-Shub soddisfa questa condizione.
MS Dousti,

2

È possibile utilizzare una funzione pseudocasuale fcome AES o ChaCha con una singola chiave casuale, crittografando un contatore. Assegna a ciascuno deiM=1000 parallel elabora un valore iniziale univoco in {0,1,...,M-1}e quindi calcolare il jth blocco casuale di bit per processo io come f(io+jM), ovvero incrementare il contatore in ogni processo di M per ogni successivo blocco di bit casuali.

Questo ti darà un RNG crittografico su ogni processo, ma non comporta necessariamente un costo in termini di prestazioni. AES è veloce se si dispone di hardware che lo supporta e ChaCha è veloce a prescindere. Naturalmente, ti consigliamo di misurarlo nella tua impostazione specifica per essere sicuro.

Entrambe le proprietà desiderate 1 e 2 ne sono direttamente soddisfatte. È inoltre conveniente che il comportamento dell'intero sistema di attività parallele sia controllato da un singolo "seme" (la chiave perf).


Se non mi interessa la forza crittografica, come si confronta ChaCha (contro) con, ad esempio, Mersenne Twister? È più veloce o più lento? Ha almeno buone proprietà statistiche? Ho provato a google, ma non sono riuscito a trovare alcun articolo che confronta questi due in un contesto non crittografico.
Jukka Suomela,


1

Puoi semplicemente usare 1000 istanze del Mersenne Twister inizializzato con diversi semi.

Puoi campionare i semi da un altro Mersenne Twister, o, per essere più sicuro della loro indipendenza, dal generatore di numeri pseudocasuale crittografico del sistema operativo (/ dev / urandom in Linux).

Il Mersenne Twister opera sempre sulla stessa sequenza ciclica, il seme controlla da dove inizi a generarlo. Con semi campionati indipendentemente, ciascun generatore si avvierà in punti diversi, in genere molto lontani, con una probabilità molto piccola di intersezione.


Quindi MT ha alcune belle proprietà speciali che garantiscono che seminare MT con un altro MT abbia senso?
Jukka Suomela,

MT ha delle proprietà di pseudo casualità dimostrabili?
Sasho Nikolov,

@Jukka: non ne sono a conoscenza. Ecco perché ho suggerito di utilizzare un altro tipo di PRNG per il seeding se si ha paura di alcune strane correlazioni sconosciute.
Antonio Valerio Miceli-Barone,

@Sasho: la pagina di Wikipedia menziona la distribuzione k e il grande periodo.
Antonio Valerio Miceli-Barone,

1
queste misure indirette mi lasciano perplesso; è sempre il caso che tutto ciò che si desidera da un PRNG sia un grande periodo eK-distribuzione? ne dubito; quelli sono solo controlli euristici di sanità mentale; in contrasto conK-indipendenza che in realtà è una proprietà pseudocasuale che garantisce la precisione in molte impostazioni. anche se combini due PRNG, almeno dovresti comunque dimostrare che almeno le proprietà euristiche di "casualità"
valgono
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.