2012-02-26 16 views
7

Tengo un enorme archivo de texto separado por líneas y quiero hacer algunos cálculos en cada línea. Necesito hacer un programa multiproceso para procesarlo porque es el procesamiento de cada línea el que toma más tiempo para completar en lugar de leer cada línea. (El cuello de botella está en el procesamiento de la CPU, en lugar de la IO)Acceso muti-threaded al mismo archivo de texto

Hay dos opciones que se me ocurrió:

1) abrir el archivo desde el hilo principal, cree un bloqueo en el identificador de archivo y pasar el file handle alrededor de los subprocesos de trabajo y luego deje que cada trabajador lea: acceda directamente al archivo

2) Cree una configuración de productor/consumidor donde solo el subproceso principal tenga acceso de lectura directa al archivo y las líneas de cada subproceso de trabajo utilizando una cola compartida

Lo que se debe saber:

  • Estoy muy interesado en el rendimiento de velocidad para esta tarea
  • Cada línea es independiente
  • estoy trabajando esto en C++, pero supongo que la cuestión aquí es un poco independiente del lenguaje

Qué opción elegirías y por qué?

+0

¿cuántos procesadores usará y qué tan grande es el archivo? – amit

+0

el archivo es de alrededor de 20 GB y en futuras implementaciones será aún mayor. Actualmente me estoy ejecutando en 4 núcleos – Alexandros

+1

@Alexandros: Sé que soy bastante tarde para responder :). Pero ¿no sería mucho más fácil asignar un bloque de líneas a cada hilo? Puede precalcular el tamaño de bloques para cada subproceso con un único puntero de archivo y luego, cada subproceso abrir el archivo y buscar esa posición pre calculada. Creo que este será un enfoque más fácil y rápido – Arunmu

Respuesta

5

Sugeriría la segunda opción, ya que será más clara en cuanto a diseño y menos complicada que la primera opción. La primera opción es menos escalable y requiere comunicación adicional entre el hilo para sincronizar el progreso en líneas de archivo. Mientras que en la segunda opción tiene un despachador que trata con IO e inicia hilos de trabajo para iniciar el cálculo, y cada subproceso computacional es completamente independiente el uno del otro, por lo tanto, le permite escalar. Además, en la segunda opción, usted separa su lógica de una manera más clara.

+0

+1 para la cola P-C. Sugeriría una clase para las comunicaciones entre subprocesos que almacena un número útil de líneas para que cada subproceso de procesamiento pase la mayor parte del tiempo procesando. Yo controlaría el flujo de este sistema creando un grupo de estos objetos de buffer de línea al inicio (es decir, otra cola P-C cargada con ellos). –

0

Si cada línea es realmente independiente y el procesamiento es mucho más lento que leer el archivo, lo que puede hacer es leer todos los datos a la vez y almacenarlos en una matriz, de modo que cada línea represente el elemento de una matriz.

Luego todos sus hilos pueden hacer el procesamiento en paralelo. Por ejemplo, si tiene 200 líneas y 4 subprocesos, cada subproceso podría realizar cálculos en 50 líneas. Además, dado que este método sería vergonzosamente paralelo, podría usar OpenMP para eso.

+0

desafortunadamente el archivo es demasiado grande para caber en la memoria – Alexandros

+1

Entonces creo que su segunda opción es buena, donde el hilo principal lee grandes trozos de datos y lo alimenta a los hilos de trabajo. – MetallicPriest

1

Si hablamos de archivos enormemente grandes, que deben procesarse con un clúster grande, MapReduce es probablemente la mejor solución.

La estructura le permite una gran escalabilidad, y ya se encarga de todo el trabajo sucio de administrar a los trabajadores y tolerar fallas para usted.
El marco está específicamente diseñado para recibir archivos leídos del sistema de archivos [originalmente para GFS] como entrada.

en cuenta que hay una implementación de código abierto del mapa-Reducir: Apache Hadoop

+1

No es necesario que exista el caso correcto para usar MapReduce. ¿Qué pasa si no hay ninguna noción de reducción real en su caso? –

+0

@ArtemBarger: map-reduce a menudo se usa con la función de identidad como paso de reducción. Un buen ejemplo es la ordenación basada en la reducción de mapas. – amit

+0

Lo sé, pero la pregunta era, ¿qué pasa si el caso de uso de Alexandros no se ajusta a esta noción? –

0

que sugeriría la segunda opción, ya que es definitivamente mejor diseño inteligente y le permitirá tener un mejor control sobre el trabajo que el trabajador hilos están haciendo.

otra parte que aumentaría el rendimiento ya que la comunicación entre hilos en ese caso es el mínimo de las dos opciones que describe

+0

¿Desde cuándo se cuenta como respuestas correctas las respuestas anteriores? –

+0

Lo siento, no lo vi en el orden correcto, lo arreglé – Alexandros

+2

@ArtemBarger No vi tu respuesta antes de publicar la mía, simplemente escribí mi opinión mientras trabajaba en otra cosa, por lo tanto, fue muy lenta. OP hizo bien en aceptar tu respuesta como más completa, más rápida y generalmente mejor, pero no hay razón para acusar a la gente de copiar y rechazar votos por ese único motivo – Lefteris

0

Otra opción es Mapa de memoria del archivo y el mantenimiento de una estructura compartida adecuadamente el manejo de la exclusión mutua de los hilos.

Cuestiones relacionadas