Pregunta Leer varios archivos en varios hilos utilizando C #, ¡Lento!


Tengo una CPU Intel Core 2 Duo y estaba leyendo 3 archivos de mi C: conducir y mostrar algunos valores coincidentes de los archivos en un EditBox en la pantalla. El proceso completo toma 2 minutos. ¡Entonces pensé en procesar cada archivo en un hilo separado y luego el proceso completo está tomando 2.30 minutos! es decir, 30 segundos más que el procesamiento de un solo hilo.

¡Estaba esperando al revés! Puedo ver los gráficos en el historial de uso de la CPU. ¿Alguna de ellas me explica lo que está pasando? aquí está mi fragmento de código.

 foreach (FileInfo file in FileList)
{

   Thread t  = new Thread(new ParameterizedThreadStart(ProcessFileData));
   t.Start(file.FullName);  

}

dónde processFileData es el método que procesa los archivos.

¡Gracias!


5
2017-11-16 04:46


origen


Respuestas:


La raíz del problema es que los archivos están en la misma unidad y, a diferencia de su procesador de doble núcleo, su unidad de disco duro solo puede hacer una cosa a la vez.

Si lee dos archivos simultáneamente, las cabezas de disco saltan de un archivo al otro y viceversa. Dado que su disco duro puede leer cada archivo en aproximadamente 40 segundos, ahora tiene la sobrecarga adicional de mover su cabeza de disco entre los tres archivos separados muchas veces durante la lectura.

La forma más rápida de leer varios archivos desde un solo disco duro es hacerlo todo en un hilo y leerlos uno tras otro. De esta manera, la cabeza solo se mueve una vez por archivo leido (al principio) y no varias veces por lectura.

Para optimizar este proceso, deberá cambiar su lógica (¿realmente necesita leer todo el contenido de los tres archivos?). O compre un disco duro más rápido / coloque los 3 archivos en tres discos duros diferentes y use subprocesos / use un raid.


11
2017-11-16 05:10



Si lee desde el disco utilizando varios subprocesos, entonces las cabezas del disco rebotarán de una parte del disco a otra a medida que cada subproceso se lea desde una parte diferente de la unidad. Eso puede reducir el rendimiento significativamente, como has visto.

Por esa razón, a menudo es mejor tener todos los accesos a los discos a través de un solo hilo, para ayudar a minimizar las búsquedas de discos.

Si su tarea está vinculada a E / S y necesita ejecutarse con frecuencia, puede consultar una herramienta como "contig" para asegurarse de que el diseño de sus archivos en el disco esté optimizado / contiguo.


3
2017-11-16 05:06



Si su procesamiento está principalmente vinculado a IO y vinculado a la CPU, tiene sentido que tome el mismo tiempo o incluso más.

¿Cómo se comparan esos archivos? Deberías pensar cuál es el cuello de botella de tu aplicación? Salida / entrada IO, CPU, memoria ...

El multihilo es solo interesante para el procesamiento vinculado a la CPU. es decir, cálculo complejo, comparación de datos en memoria, clasificación, etc.


1
2017-11-16 04:50



Debido a que su proceso está enlazado a IO, debe dejar que el sistema operativo haga sus hilos por usted. Consulte FileStream.BeginRead () para ver un ejemplo de cómo poner en cola sus lecturas. Su método EndRead () puede activar su próxima solicitud para leer su siguiente bloque de datos apuntando a sí mismo para manejar cada bloque subsiguiente completado.

Además, con la creación de subprocesos adicionales, el sistema operativo tiene que administrar más subprocesos. Y si se selecciona una CPU diferente para manejar la lectura completa, ha perdido todo el almacenamiento en caché de la CPU donde se originó su subproceso.

Como ha encontrado, no puede "acelerar" una aplicación simplemente agregando hilos.


0
2017-11-16 05:01