Esta pregunta se relaciona principalmente con un problema práctico de ingeniería de software, pero me gustaría saber si los teóricos podrían proporcionar más información al respecto.
En pocas palabras, tengo una simulación de Monte Carlo que usa un generador de números pseudoaleatorio, y me gustaría paralelizarlo para que haya 1000 computadoras que ejecuten la misma simulación en paralelo. Por lo tanto, necesito 1000 secuencias independientes de números pseudoaleatorios.
¿Podemos tener 1000 flujos paralelos con las siguientes propiedades? Aquí debería ser un PRNG muy conocido y ampliamente estudiado con todo tipo de buenas propiedades teóricas y empíricas.
Las transmisiones son probablemente tan buenas como las que obtendría si simplemente usara y dividiera la transmisión generada por en 1000 transmisiones.X
Generando el siguiente número en cualquier corriente es (casi) tan rápido como la generación de la siguiente número con .
Dicho de otra manera: ¿podemos obtener múltiples transmisiones independientes "gratis"?
Por supuesto, si simplemente usamos , siempre descartando 999 números y escogiendo 1, entonces ciertamente tendríamos la propiedad 1, pero perderíamos en el tiempo de ejecución por el factor 1000.
Una idea simple sería usar 1000 copias de , con semillas 1, 2, ..., 1000. Esto ciertamente sería rápido, pero no es obvio si los flujos tienen buenas propiedades estadísticas.
Después de buscar en Google, he encontrado, por ejemplo, lo siguiente:
La biblioteca SPRNG parece estar diseñada exactamente para este propósito y es compatible con múltiples PRNG .
El tornado de Mersenne parece ser un PRNG popular hoy en día, y encontré algunas referencias a una variante que es capaz de producir múltiples flujos en paralelo.
Pero todo esto está tan lejos de mis propias áreas de investigación, que no pude entender qué es realmente el estado del arte y qué construcciones funcionan bien no solo en teoría sino también en la práctica.
Algunas aclaraciones: no necesito ningún tipo de propiedades criptográficas; Esto es para el cálculo científico. Necesitaré miles de millones de números aleatorios, por lo que podemos olvidar cualquier generador con un período de .
Editar: no puedo usar un verdadero RNG; Necesito un PRNG determinista. En primer lugar, ayuda mucho con la depuración y hace que todo sea repetible. En segundo lugar, me permite hacer, por ejemplo, la búsqueda de mediana de manera muy eficiente al explotar el hecho de que puedo usar el modelo de múltiples pasos (ver esta pregunta ).
Edición 2: hay una pregunta estrechamente relacionada @ StackOverflow: generador de números pseudoaleatorios para el entorno de clúster .
fuente
Respuestas:
Puede utilizar una evolución del algoritmo Mersenne Twister desarrollado por Saito y Matsumoto:
Twister Mersenne rápido orientado a SIMD (SFMT)
SFMT es un generador de Registro de desplazamiento de retroalimentación lineal (LFSR) que genera un entero pseudoaleatorio de 128 bits en un solo paso. SFMT está diseñado con el paralelismo reciente de las CPU modernas, como la canalización en varias etapas y las instrucciones SIMD (por ejemplo, entero de 128 bits). Admite enteros de 32 y 64 bits, así como punto flotante de doble precisión como salida. SFMT es mucho más rápido que MT, en la mayoría de las plataformas. No solo se mejora la velocidad, sino también las dimensiones de las equidistribuciones con precisión de v-bit. Además, la recuperación del estado inicial en exceso 0 es mucho más rápida. Ver Tesis de Maestría de Mutsuo Saito para más detalles .
El período varía de a 2 216091 - 1 .2607- 1 2216091- 1
El uso de un mismo generador de números al azar para generar múltiples flujos independientes cambiando los valores iniciales puede causar un problema (con una probabilidad insignificantemente pequeña). Para evitar el problema, se prefiere usar diferentes parámetros para cada generación. Esta técnica se llama creación dinámica de los parámetros MT.
En el código fuente SFMT puede encontrar algunos ejemplos de conjuntos de parámetros (de períodos variables) y un script awk para convertir un archivo CSV en un conjunto de parámetros compilable. También hay una herramienta llamada " Creación dinámica de generadores Mersenne Twister ".
Los autores desarrollaron recientemente otra versión modificada de Mersenne Twister, Mersenne Twister para procesadores gráficos , diseñada para ejecutarse en GPU y aprovechar sus hilos de ejecución paralelos nativos. La característica clave es la velocidad: enteros aleatorios cada 4.6ms en una GeForce GTX 260.5 × 107 7
Los períodos de secuencia generada son , 2 23209 - 1 y 2 44497 - 1 para la versión de 32 bits, y 2 23209 - 1 , 2 44497 - 1 , 2 110503 - 1 para la versión de 64 bits. Es compatible con 128 conjuntos de parámetros para cada período, en otras palabras, puede generar 128 secuencias de números pseudoaleatorios independientes para cada período. Hemos desarrollado Dynamic Creator para MTGP, que genera más conjuntos de parámetros211213- 1 223209- 1 244497- 1 223209- 1 244497- 1 2110503- 1
De hecho, proporcionan una herramienta MTGPDC para crear hasta conjuntos de parámetros (es decir, flujos independientes).232
El algoritmo pasa las principales pruebas de aleatoriedad como Diehard y NIST.
También está disponible un documento preliminar sobre arXiv: una variante de Mersenne Twister adecuada para procesadores gráficos
fuente
Parece que hay muchas formas de abordar este problema, pero una forma sencilla sería utilizar el Blum Blum Shub PRNG. Este PRNG se define por la relación de recurrencia , donde N es un semiprime. Para obtener un bit aleatorio de esto, simplemente puede tomar la paridad de bits de x i . Lo bueno de esto es que dado que x i + k = x 2 k i mod N = x 2 k mod λ ( N ) iXi + 1= x2yo mod N norte Xyo puede calcular directamente cualquier paso en la constante de tiempo en k (es decir, O ( log ( N ) 3 ) o más rápido dependiendo del algoritmo de multiplicación que utilice para el exponencial modular). Por lo tanto, si tienemáquinas M , entonces para la máquina indexada por y puede usar el generador x i + 1 , y = x 2 M mod λ ( N ) i mod N , donde x 0 , y = xXi + k= x2kyo mod N= x2k mod λ(N)yomod N k O ( log( N)3) METRO y Xi + 1 , y= x2METROmod λ(N)yo mod N , dondex0es su semilla. Convenientemente, esto genera exactamente el mismo flujo de números como si usara un solo flujo y distribuye su salida a cada una de las máquinas.X0 , y= x2y mod λ(N)0 0 mod N X0 0
Sin embargo, este no es el PRNG más rápido, por lo que solo será útil si la sobrecarga de lo que esté haciendo en la simulación es significativamente mayor que el costo del PRNG. Sin embargo, vale la pena señalar que será mucho más rápido para ciertas combinaciones de y N que otras, particularmente si la representación binaria de 2 M mod λ ( N ) contiene pocos 1s o es pequeña.METRO norte 2METRO mod λ(N)
fuente
fuente
Esto le dará un RNG criptográfico en cada proceso, pero no necesariamente conlleva un costo de rendimiento. AES es rápido si tiene hardware que lo admita, y ChaCha es rápido independientemente. Por supuesto, querrá medir esto en su configuración específica para estar seguro.
fuente
Ahora hay una función de salto para SFMT (una implementación rápida de Mersenne Twister).
Esto me permite inicializar 1000 MT para que no haya superposición de ciclos. Y SFMT debería ser más rápido que MTGP. Casi perfecto para mis propósitos.
fuente
Solo puede usar 1000 instancias del Mersenne Twister inicializado con diferentes semillas.
Puede probar las semillas de otro Mersenne Twister o, para estar más seguro de su independencia, del generador de números pseudoaleatorios criptográficos del sistema operativo (/ dev / urandom en Linux).
El Mersenne Twister siempre funciona en la misma secuencia cíclica, la semilla controla dónde comienzas a generarlo. Con semillas muestreadas independientemente, cada generador comenzará en puntos diferentes, típicamente muy lejanos, con una probabilidad muy pequeña de intersección.
fuente