2010-09-09 20 views
11

Actualización: Acabo de encontrar this documentation page. Desearía que hubiera un enlace desde the documentation that I'd been using, que parecía ser el documento definitivo de la API. Pero tal vez es un trabajo nuevo, inédito.Cómo hacer una estrategia en Haskell Control.Parallel.Strategies?

Actualización 2: Esta documentación me ha dado una idea mucho mejor sobre cómo usar el módulo Control.Parallel.Strategies. Sin embargo, aún no he resuelto el problema ... ver el final de la pregunta.

He estado tratando de usar parListChunk o algunas otras funciones de control paralelo en Haskell. Pero no puedo descifrar cómo usarlos. Advertencia: soy un novato Haskell. Aprendí algunas cosas sobre programación funcional con Scheme hace unos 20 años (!).

Aquí es mi función no parallelized:

possibKs n r = [ (k, (hanoiRCountK n k r)) | k <- [1 .. n-1] ] 

quiero poner en paralelo, algo como esto ingenuo intento:

possibKs n r 
    | n < parCutoff = results 
    | otherwise  = parListChunk parChunkSize results 
    where results = [ (k, (hanoiRCountK n k r)) | k <- [1 .. n-1] ] 

Pero esa estructura no es la adecuada para parListChunk. Los documentos dicen:

parListChunk :: Int -> Strategy a -> Strategy [a] 

parListChunk sequentially applies a strategy to chunks (sub-sequences) of a list in parallel. Useful to increase grain size

Bueno, eso es lo que quiero. Pero, ¿cómo usarlo? No he podido encontrar ningún ejemplo de esto. Si entiendo la declaración de tipo, parListChunk es una función que toma un Int y un Strategy<a> (toma prestada la notación de tipo parametrizada en C++ para ayudarme a verificar que realmente estoy entendiendo este derecho), y devuelve un Strategy<[a]>. En mi caso estoy tratando con Int para a así que parListChunk necesitará un argumento Int y un Strategy<Int>. Entonces, ¿qué es un Strategy y cómo puedo producir uno? Y una vez que he utilizado con éxito parListChunk, ¿qué hago con el Strategy que escupe?

El Strategy type is defined así:

type Strategy a = a -> Done 

(. Y eso es todo la documentación de Estrategia) Así que un Strategy<Int> es una función que toma un parámetro de tipo int y devuelve Hecho. Aparentemente hace que su argumento sea evaluado en un momento determinado o algo así. ¿Dónde obtengo uno y qué tipo debo usar?

Las siguientes funciones parecen volver Estrategias:

sPar :: a -> Strategy b 
sSeq :: a -> Strategy b 
r0 :: Strategy a 
rwhnf :: Strategy a 

Pero ninguno de ellos le permiten determinar el parámetro de tipo - que producen un Strategy<b> cuando das parámetro a, o de lo contrario no llegan a suministrar parámetro a! ¿¿Que pasa con eso?? Más allá de eso, no tengo idea de lo que significan.

Lo que encontrar un ejemplo de la función similar en parList being used SO:

return . maximum $ map optimize xs `using` parList 

Utiliza esta función cobarde using, que se declara:

using :: a -> Strategy a -> a 

parece justo ... en mi caso Probablemente quiero que a sea [Int], por lo que se necesita una lista de Ints y un Strategy<[Int]> y (¿aplica algo? ¿Aplica la estrategia a la lista? Y) devuelve una lista de Ints. Así que traté de seguir el ejemplo PARLIST y cambiado de guardia otherwise a:

| otherwise  = results `using` parListChunk parChunkSize 

pero debo admitir que todavía estoy disparar en la oscuridad ... Yo no puedo seguir las firmas de tipos alrededor. Así que no es demasiado sorprendente que el anterior es un error:

Couldn't match expected type `[(Int, Integer)]' 
     against inferred type `a -> Eval a' 
Probable cause: `parListChunk' is applied to too few arguments 
In the second argument of `using', namely 
    `parListChunk parChunkSize' 
In the expression: results `using` parListChunk parChunkSize 

Puede alguien decirme lo que se utilizará para el argumento Strategy a a parListChunk? y cómo usar el Strategy [a] devuelto por parListChunk?

Nueva parte

En cuanto a Basic Strategies, yo creo que tenga que utilizar la estrategia rseq. Probablemente. Así que intento

| otherwise  = results `using` (parListChunk parChunkSize rseq) 

Pero GHC dice que rseq es "no en el alcance". These API docs dicen que no hay rseq en el paquete pero sSeq parece haberlo reemplazado. OK, entonces usé sSeq, pero tampoco está en el alcance. Aunque estoy importando Control.Parallel.Strategies.

¿Alguna pista? Por cierto solía tener estos mensajes acerca de los paquetes de carga:

Loading package deepseq-1.1.0.0 ... linking ... done. 
Loading package parallel-2.2.0.1 ... linking ... done. 

Así que al parecer lo que dice la versión del paquete paralelo que tengo: 2.2.0.1. Pero no veo información en el API docs sobre qué versión se describe allí. Si no debo usar rseq o sSeq, ¿qué debería usar? ¿Cómo es que Edward pudo usar parList?

Respuesta

2

Bien, obtuve el código funcionando. Lo tengo a compilar utilizando rwhnf en lugar de rseq:

| otherwise  = results `using` (parListChunk parChunkSize rwhnf) 

Según this source code, rwhnf se renombró a rseq en la versión 3. Así que supongo que mi versión del paquete paralelo es obsoleto con respecto a this documentation. : -S

Supongo que es parte del precio de usar paquetes "experimentales".

De todos modos, el código se compila y se ejecuta. Si está haciendo algo útil con el paralelismo es otra cuestión ...

+2

Asegúrese de ejecutar el ejecutable con + RTS -N para usar múltiples núcleos. Si habilita + RTS -s para mostrar estadísticas, puede ver qué tan eficientemente se está repartiendo el trabajo entre los núcleos. Para una sintonización más detallada, use ThreadScope (http://research.microsoft.com/en-us/projects/threadscope/). –

+0

Gracias, @John.En WinGCHi, tengo "ghc --interactive -threaded" en las opciones de inicio de GHCi. ¿Supongo que no es suficiente? ¿Puedo incluso ejecutar programas multiproceso dentro de WinGCHi? – LarsH

+0

IIRC ghci siempre usa el tiempo de ejecución con subprocesos (por ejemplo, "threads está implícito"). Simplemente especifique las opciones de tiempo de ejecución que desea en las opciones de inicio y debería estar bien. Si no usa -N, el valor predeterminado es permanecer en un núcleo incluso con el tiempo de ejecución enhebrado. –

Cuestiones relacionadas