Mapa paralelo en haskell
parallel-processing multicore (2)
¿Hay algún sustituto del map
que evalúe la lista en paralelo? No necesito que sea perezoso.
Algo así como: pmap :: (a -> b) -> [a] -> [b]
dejándome pmap expensive_function big_list
y tengo todos mis núcleos al 100%.
Además de usar estrategias explícitas como Tom ha descrito, el paquete parallel también exporta parMap
:
parMap :: Strategy b -> (a -> b) -> [a] -> [b]
donde el argumento de la estrategia es algo así como rdeepseq
.
Y también hay parMap
en el paquete par- parMap
(sales del puro Haskell, y entras en una mónada paralela):
parMap :: NFData b => (a -> b) -> [a] -> Par [b]
El paquete par-monad se documenta aquí .
Sí, vea el paquete paralelo :
ls `using` parList rdeepseq
evaluará cada elemento de la lista en paralelo a través de la estrategia rdeepseq
. Tenga en cuenta que el uso de parListChunk
con un buen valor de trozo podría dar un mejor rendimiento si sus elementos son demasiado baratos para obtener un beneficio al evaluar cada uno en paralelo (porque ahorra en chispas para cada elemento).
EDIT: Basado en su pregunta, creo que debería explicar por qué esta es una respuesta. ¡Es porque Haskell es perezoso! Considera la afirmación
let bs = map expensiveFunction as
Nada ha sido evaluado. Acaba de crear un procesador que asigna funciones expensiveFunction
. Entonces, ¿cómo lo evaluamos en paralelo?
let bs = map expensiveFunction as
cs = bs `using` parList rdeepseq
Ahora no use la lista de bs
en sus futuros cálculos, en su lugar use la lista de cs
. IOW, no necesita un mapa paralelo, puede usar los mapas regulares (perezosos) y una estrategia de evaluación paralela.
EDITAR: Y si miras a tu alrededor lo suficiente, verás la función parMap que hace lo que mostré aquí, pero envuelta en una función auxiliar.
En respuesta a su comentario, ¿el código de abajo no funciona para usted? esto funciona para mi.
import Control.Parallel.Strategies
func as =
let bs = map (+1) as
cs = bs `using` parList rdeepseq
in cs