2011-11-03 10 views
8

Soy un novato que usa Java para hacer algo de procesamiento de datos en archivos csv. Para eso utilizo las capacidades de subprocesamiento múltiple de Java (pools of threads) para importar en lotes los archivos csv en Java y realizar algunas operaciones en cada una de sus líneas. En mi quad-core, el multihilo acelera mucho el proceso.cómo hacer multiprocesamiento en Java, y qué velocidad espera esperar?

Tengo curiosidad por saber cómo y si el multiprocesamiento aceleraría aún más las operaciones? Si es así, ¿hay algún tutorial disponible en alguna parte? (Tutorial básico de Java menciona una clase, pero no estoy lo suficientemente familiarizado con la sintaxis de entender la clase por mí mismo:

de http://download.oracle.com/javase/tutorial/essential/concurrency/procthread.html:

mayoría de las implementaciones de la máquina virtual Java se ejecutan como una sola proceso. una aplicación Java puede crear procesos adicionales utilizando un objeto ProcessBuilder. aplicaciones multiproceso están más allá del alcance de esta lección [donde se explicaron entonces?].

+3

¿Está obligado CPU o E/S de la envolvente? Los discos duros son significativamente más lentos que los procesadores. Además, los subprocesos generalmente son más livianos para alternar entre y compartir datos entre los procesos. Si su programa está esperando constantemente el disco, no va a importar mucho de ninguna manera. –

+0

Tengo una cola de docenas de archivos csv para importar en mi aplicación java. Utilizo un conjunto de hilos (siete hilos, precisamente) para importarlos más rápido que uno después del otro - en este momento puedo importar 7 archivos csv "a la vez" - uno por hilo. ¿Podría acelerar esto aún más con multiprocesamiento? ¿Cómo es el multiprocesamiento útil para el paralelismo en una sola computadora en general? – seinecle

+0

Por lo general, me parece que puede mejorar el rendimiento de un solo hilo mucho más que el solo 4x (lo mejor que puede esperar de 4 núcleos si está vinculado a la CPU) Me aseguraría de haber perfilado y optimizado completamente el código que tiene primero . –

Respuesta

4

Tengo curiosidad por saber cómo/si multiprocesamiento podría acelerar las operaciones aún más?

No, de hecho, es probable que lo empeore. Si tuviera que cambiar de multihilo a multiprocesamiento, entonces lanzaría efectivamente la JVM varias veces. Iniciar una JVM no es un simple esfuerzo. De hecho, la forma en que se inicia la JVM en su máquina de escritorio es diferente de la forma en que una compañía empresarial inicia su JVM, solo para reducir el tiempo de espera para que los applets se inicien para el usuario final típico.

+0

thx Tim ... de hecho encontré otros hilos de discusiones apuntando a esto. Para el lector interesado, descubra esta discusión más tarde: http: //stackoverflow.com/questions/2006035/how-to-create-a-process-in-java and http://www.javabeat.net/tips/8-using -the-new-process-builder-class.html – seinecle

+0

Tan pronto como empiezo a pensar en el multiprocesamiento, mi cerebro cambia al modo C/C++ donde el costo de inicio no es * tan * alto. pero estamos hablando de Java, y lleva un mes y un día, más la mitad de su ram disponible, (podría ser un poco exagerado) iniciar una nueva JVM, que cada proceso adicional requerirá. Buen punto, Tim. – ObscureRobot

+0

Bueno, descubrí que esto podría ser una solución para reducir el tiempo de inicio: http://martiansoftware.com/nailgun/ – seinecle

1

Compruebe los documentos en su JVM para ver si admite subprocesamiento múltiple. Estoy bastante seguro de que los rayos del sol sí. Java Concurrency In Practice es el lugar para comenzar a realizar subprocesos múltiples.

La primera parte de su pregunta es: ¿es el multiprocesamiento superior al multihilo, desde una perspectiva de rendimiento? En un sistema con soporte robusto de subprocesos múltiples, los subprocesos siempre deben ser superiores a los procesos, desde una perspectiva de rendimiento. Hay más aislamiento entre subprocesos (sin memoria compartida, a menos que se configure explícitamente a través de un mecanismo de IPC), por lo que es posible que desee ir por la ruta de multiproceso para evitar que los subprocesos peligrosos se pisen entre sí.

Para el procesamiento de datos, los hilos deben ser la mejor manera de proceder. Si los hilos en su máquina local no son suficientes, omitiría una solución multiproceso e iría directamente a un sistema map-reduce como Hadoop.

En cuanto a por qué las aplicaciones multiproceso son mencionado, creo que el autor quiere estar completo. Aunque no se proporciona un tutorial, es un enlace a la documentación adicional. La gran desventaja de usar multiprocesamiento es que debe lidiar con la comunicación entre procesos. A diferencia de los hilos, no puedes simplemente compartir algo de memoria y lanzar algunos mutex alrededor y llamarlo un día.


Según los comentarios, parece que hay cierta confusión acerca de qué es realmente el "multiprocesamiento". Los hilos son construcciones que deben ser creadas por su código. Hay API para la creación y administración de subprocesos. Los procesos, sin embargo, se pueden crear a mano en la línea de comando. En un cuadro Unix, haga lo siguiente para ejecutar cuatro instancias (procesos) de foo. Tenga en cuenta que se requiere el & final.

$ ./foo & ./foo & ./foo & ./foo & 

Ahora bien, si usted tiene un archivo de entrada, bar que foo necesita procesar, usar algo como split a dividirla en cuatro segmentos iguales, y ejecutar foo en él:

$ ./foo bar.0 > bar.0.out & ./foo bar.1 > bar.1.out & ./foo bar.2 > bar.2.out & ./foo bar.3 > bar.3.out & 

Por último, Deberá combinar los archivos bar.?.out. Hacer una prueba como esta debería darle una idea de si el uso de procesos pesados ​​es una buena idea para su aplicación.Si ya ha creado una aplicación multiproceso, probablemente esté bien. Pero puede ejecutar algunos experimentos para ver si los procesos funcionan mejor. Una vez que esté seguro de que los procesos son el camino a seguir, reorganice su código para usar ProcessBuilder para acelerar los procesos usted mismo.

+0

Gracias, pero esto no responde mi pregunta. Ya uso multihilo (¡funciona bien!) Y me gustaría encontrar una fuente o una explicación detallada sobre cómo/por qué/cuándo el multiprocesamiento mejoraría el rendimiento. Por cierto, revisé Java Concurrency in Practice: no evoca el multiprocesamiento, solo el multihilo. – seinecle

+0

@seinecle Mi conjetura es: a menos que te encuentres con las limitaciones de memoria/CPU de un solo proceso y que estés haciendo cosas realmente pesadas, probablemente rara vez o nunca. La comunicación entre procesos engullirá parte de la ganancia de rendimiento, y el engendrar nuevos procesos a menudo es un poco caro, por lo que solo tiene sentido para las tareas de larga ejecución. Una ventaja, supongo, es la estabilidad. Si un proceso falla, el resto permanece intacto. Google Chrome utiliza un proceso separado por ficha para asegurarse de que los sitios que arruinan su día no anulen todo el navegador. –

+0

En un sistema con enhebrado robusto (prácticamente cualquier Unix o Windows moderno), se prefiere el multiprocesamiento al multiprocesamiento. La razón es que hay menos sobrecarga asociada con los hilos, por lo que puede girarlos más rápidamente y matarlos. También obtienes memoria compartida, lo cual es una buena ventaja. En sistemas más antiguos, el multiprocesamiento era el camino a seguir. Es por eso que Apache 1.x es multiproceso y Apache 2.x es multihilo, y todos usan Apache 2 ahora. – ObscureRobot

1

Cada desarrollador debe tener algún conocimiento acerca de la ley de Amdahl entender cómo el procesamiento multi aceleraría en base a las condiciones dadas.

La ley de Amdahl es un modelo para la relación entre la aceleración esperada de las implementaciones paralelizadas de un algoritmo relativo al algoritmo serie, bajo el supuesto de que el tamaño del problema permanece igual cuando se paraleliza.

Esta es una buena lectura: la ley de Amdahl

Amdahl's law

+0

Un poco ortogonal a la pregunta, ya que puedes minimizar el componente serial de tu algoritmo usando threads * o * procesos, pero vale la pena considerarlos – ObscureRobot

+0

Gracias, pero honestamente ... esto está muy lejos de mi pregunta. Estoy pidiendo específicamente recomendaciones sobre cómo implementar el multiprocesamiento en Java. ¡No se trata de leyes generales sobre este tema, realmente! – seinecle

+0

Puede referir esto también. http://mpc.uci.edu/wget/www.tc.cornell.edu/Services/Edu/Topics/ParProgCons/index.html # sec6 –

1

La ganancia está determinada por cuánto tiempo se tarda en asignar/reducir los datos.

Si, por ejemplo, los archivos se cargan en varias máquinas, para empezar (piense en ello como sharding el sistema de archivos), no hay retraso de obtener los datos. Si los datos provienen de una sola ubicación, está limitado por ese mecanismo.

A continuación, los datos tienen que ser combinado/agregada, sin saber más, imposible de adivinar. Si todo el procesamiento depende de tener todos los datos, es un golpe más alto que si los resultados finales se pueden calcular de forma independiente.

Usted tiene un número muy pequeño de archivos muy pequeños: a no ser que lo que está haciendo es computacionalmente costosa, dudo que sería la pena el esfuerzo, pero es difícil de decir. Suponiendo que no hay cuellos de botella en la red o en el disco obtendrá (muy) una aceleración aproximada lineal con un delta para agregar resultados. La verdadera aceleración/delta depende de un grupo de factores de los que no sabemos mucho en este momento.

otoh, se podría establecer una configuración de Hadoop pequeña y hay que probarlo y ver qué pasa.

0

Para muchos casos de uso, el multihilo tiene menos sobrecarga que el multiprocesamiento cuando se compara el desove de un hilo con el proceso de desove, y se compara la comunicación entre subprocesos versus la comunicación entre procesos.

Sin embargo, hay escenarios donde multihilo puede degradar el rendimiento hasta el punto que un solo hilo supera varios subprocesos, como los casos gravemente afectados por false sharing. Con el multiprocesamiento, dado que cada proceso tiene su propio espacio de memoria, no hay posibilidad de que se produzca un intercambio falso y la solución de multiprocesamiento puede superar a la solución de subprocesamiento múltiple.

En general, algunos análisis deberán realizarse al momento de elegir una solución de programación concurrente ya que la mejor solución de rendimiento puede variar sobre una base de caso por caso.No se puede asumir que el multihilo supera al multiprocesamiento dado que existen situaciones contra intuitivas en las que el multihilo funciona peor que un solo hilo. Cuando el rendimiento es una consideración importante, ejecute los puntos de referencia para comparar soluciones de procesos individuales de un solo hilo frente a procesos múltiples frente a multiprocesamiento para asegurarse de que realmente está obteniendo los beneficios de rendimiento que se esperan.

En una nota rápida, hay otras consideraciones además del rendimiento al elegir una solución.

1

Hay varias formas de iniciar un nuevo proceso en Java:

  1. ProcessBuilder.start()
  2. Runtime.exec() obras alrededor ProcessBuilder
  3. Apache Commons Exec que trabaja alrededor Runtime.exec()

Con ProcessBuilder:

ProcessBuilder pb = 
new ProcessBuilder("myCommand", "myArg1", "myArg2"); 
Map<String, String> env = pb.environment(); 
env.put("VAR1", "myValue"); 
env.remove("OTHERVAR"); 
env.put("VAR2", env.get("VAR1") + "suffix"); 
pb.directory(new File("myDir")); 
File log = new File("log"); 
pb.redirectErrorStream(true); 
pb.redirectOutput(Redirect.appendTo(log)); 
Process p = pb.start(); 
assert pb.redirectInput() == Redirect.PIPE; 
assert pb.redirectOutput().file() == log; 
assert p.getInputStream().read() == -1; 

Con Runtime:

Runtime r = Runtime.getRuntime(); 
Process p = r.exec("firefox"); 
p.waitFor(10, TimeUnit.SECONDS); 
p.destroy(); 

con Apache Commons Exec:

String line = "AcroRd32.exe /p /h " + file.getAbsolutePath(); 
CommandLine cmdLine = CommandLine.parse(line); 
DefaultExecutor executor = new DefaultExecutor(); 
int exitValue = executor.execute(cmdLine); 

Principales diferencias entre multiprocesamiento y subprocesos múltiples de this:

  • La diferencia clave entre multiproceso y multihilo es ese multiprocesamiento permite un sistema tener más de dos CPU agregadas al sistema, mientras que el multihilo permite que un proceso genere múltiples hilos para aumentar la velocidad de un sistema.
  • El sistema de multiprocesamiento ejecuta múltiples procesos simultáneamente, mientras que el sistema de subprocesos múltiples permite ejecutar múltiples hilos de un proceso simultáneamente.
  • Crear un proceso puede consumir tiempo e incluso agotar los recursos del sistema. Sin embargo, la creación de hilos es económica ya que los hilos pertenecientes al mismo proceso comparten las pertenencias de ese proceso.
  • El multiprocesamiento se puede clasificar en multiprocesamiento simétrico y multiprocesamiento asimétrico, mientras que el multihilo no se clasifica más.

enlaces adicionales:

Cuestiones relacionadas