2012-03-13 8 views
8

¿Qué lista, matriz o secuencia son más eficientes para el procesamiento en paralelo y pueden implementar fácilmente operaciones paralelas como parmap, parfilter, etc.?Colecciones de datos paralelos en F #

EDITAR: Gracias por las sugerencias. Array.Parallel parece una buena opción. También compruebo PSeq.fs y tengo una pregunta sobre cómo funciona el pmap a continuación.

let pmap f xs = 
    seq { for x in xs -> async { return f xs } } 
    |> Async.Parallel 
    |> Async.RunSynchronously 

¿Se genera un nuevo hilo para cada elemento de la secuencia? Si es así, ¿hay alguna forma de dividir el seq en fragmentos y crear una nueva tarea para que cada fragmento se evalúe en paralelo?

También me gustaría ver si hay alguna implementación similar pmap para la lista. Descubrí que Tomas tiene una implementación de ParallelList en su publicación de blog here. Pero no estoy seguro de si convertir una lista en una matriz para realizar una evaluación paralela no implica demasiada sobrecarga y si puede evitarse.

EDITAR: Gracias por todas sus entradas. Tomás respondió mi pregunta original.

responder a mi propia pregunta en la primera edición:

he intentado romper una gran lista en trozos y luego se aplica a cada sublista asíncrono.

let pmapchunk f xs = 
    let chunks = chunk chunksize xs 
    seq { for chunk in chunks -> async { return (Seq.map f) chunk } } 
    |> Async.Parallel 
    |> Async.RunSynchronously 
    |> Seq.concat 

Los resultados: map: 15s, pmap: 7s, pmapchunk: 10s.

+1

Depende, pero casi seguro querrás 'Array.Parallel' y no' async'. –

Respuesta

9

Hay una implementación paralela de algunas operaciones de matriz en la # biblioteca F. En general, trabajar con matrices probablemente sea más eficiente si las operaciones individuales toman mucho tiempo.

  • Eche un vistazo al módulo Array.Parallel. Contiene funciones para crear una matriz (init), para realizar cálculos con elementos (map) y también la función choose que se puede usar para implementar el filtrado.

Si está escribiendo una compleja serie de operaciones que son bastante simples, pero hay una gran cantidad de ellas, necesitará usar PLINQ, que paraleliza toda la línea de tubería en lugar de paralelizar solo operaciones individuales (como el mapa).

  • Tome una mirada en el módulo de PSeqF# PowerPack para un envoltorio de usar # F - se define pseq<'T> tipo y las funciones habituales para trabajar con ellos. Este blog post también contiene información útil.
+0

gracias. Me encontré con 'Array.Parallel',' PSeq', y '' ParallelList' en tu blog. Los dos últimos no parecen estar incluidos en la referencia de la biblioteca, solo 'Array.Parallel' sí. He editado la pregunta, por favor, eche un vistazo. – vis

+1

"trabajar con matrices probablemente sea más eficiente si las operaciones individuales toman mucho tiempo"? Esperaría que las matrices fueran relativamente más rápidas cuando las operaciones individuales son rápidas. –

0

Realísticamente, la sobrecarga de cambiar los tipos de colección es pequeña en comparación con el costo de hacer una operación asincrónica, por lo que el tipo de colección no importa.

Dicho esto, List tiende a malla más bien con F # sintaxis lo que puede ser más agradable

+4

'list' es el peor tipo de colección posible para programación paralela porque es embarazosamente secuencial. –

1

Junto con la sugerencia de Tomás mirar Array.Parallel, vale la pena señalar que las matrices (arrays y colecciones con respaldo) siempre será el más eficiente para atravesar (mapa, iter, ...) ya que están almacenados en la memoria contigua.

Cuestiones relacionadas