2011-05-26 38 views
7

sólo quería probar las colecciones paralelas un poco y me utilizó la siguiente línea de código (en REPL):¿Por qué no es más rápido usando colecciones paralelas?

(1 to 100000).par.filter(BigInt(_).isProbablePrime(100)) 

contra:

(1 to 100000).filter(BigInt(_).isProbablePrime(100)) 

Pero la versión paralela no es más rápida. De hecho, incluso se siente un poco más lento (Pero realmente no he medido eso).

¿Alguien tiene una explicación para eso?

Edición 1: Sí, tengo un procesador multi-core

Edición 2: Está bien, "resuelto" el problema mismo. La implementación de isProbablePrime parece ser el problema y no las colecciones paralelas. Reemplacé isProbablePrime con otra función para probar la primalidad y ahora obtengo una aceleración esperada.

+0

El paralelismo es solo más rápido si le permite obtener más hardware de arranque, y tiene gastos generales. ¿Scala está configurado para hacer uso de los núcleos extra? –

+0

No sabía que tenía que configurar nada. ¿Tienes más información sobre esto? –

+4

No se necesita configuración aquí; Scala busca el número de núcleos disponibles y delega el trabajo en un grupo de Fork-Join del tamaño adecuado. –

Respuesta

6

Tanto con rangos secuenciales como paralelos, filter generará una estructura de datos vectorial: Vector o ParVector, respectivamente.

Este es un problema conocido con vectores paralelos que se generan a partir de colecciones de rango: los métodos de transformador (como filter) para vectores paralelos no construyen el vector en paralelo.

Ya se ha desarrollado una solución para esto que permite la construcción paralela eficiente de vectores, pero aún no se implementó. Le sugiero que presente un archivo ticket, para que se pueda solucionar en la próxima versión.

+0

No creo que ese sea el problema. Por ejemplo, si hago algo como '(1 a 10000) .par.filter (x => {Thread.sleep (1); true})' la versión paralela es mucho más rápida que la secuencial. Entonces la ejecución en paralelo parece funcionar, pero parece que isProbablePrime no puede ejecutarse en más de un hilo a la vez (por la razón que sea). –

+0

Eso es verdad, lo es. Sin embargo, en ese caso, la cantidad de tiempo dedicado al procesamiento de cada elemento es mucho mayor que el tiempo necesario para construir el 'ParVector' (que actualmente se realiza de forma secuencial), por lo que no se observa el tiempo dedicado a la creación del vector. El 'isProbablePrime' también debe hacerse en paralelo, sin embargo, los beneficios de ejecutarlo en paralelo deben enmascararse mediante la construcción secuencial al final. – axel22

+1

Supongo que 'isProbablePrime' tiene porciones bastante grandes de código sincronizado porque otra cosa que noté es que la versión secuencial maximiza un núcleo pero la versión paralela distribuye la carga de manera bastante equitativa. Supongo que debería dejar de usar 'isProbablePrime' para probar cosas paralelas :) –

Cuestiones relacionadas