2011-09-29 23 views
8

Tengo un proceso de larga ejecución que lee archivos de gran tamaño y escribe archivos de resumen. Para acelerar las cosas, estoy procesar varios archivos al mismo tiempo usando viejos hilos regulares:Hilos vs procesos en .NET

ThreadStart ts = new ThreadStart(Work); 
Thread t = new Thread(ts); 
t.Start(); 

Lo que he encontrado es que incluso con hilos separados leer archivos separados y sin bloqueo entre ellos y por medio de 4 hilos en un 24 cuadro de puntuación, ni siquiera puedo obtener hasta un 10% en la CPU o un 10% en la E/S de disco. Si uso más hilos en mi aplicación, parece funcionar aún más lentamente.

Supongo que estoy haciendo algo mal, pero cuando me da curiosidad es que si comienzo el exe por segunda y tercera vez, entonces procesa los archivos dos y tres veces más rápido. Mi pregunta es, ¿por qué no puedo obtener 12 hilos en mi única aplicación para procesar datos y gravar el equipo, así como 4 hilos en 3 instancias de mi aplicación?

He creado un perfil de la aplicación y las funciones que requieren más tiempo y llamadas frecuentes son todas las llamadas de procesamiento de cadenas.

+6

Imposible decir sin el código real haciendo el procesamiento de archivos. –

+5

¿Qué le dijo el perfil acerca de dónde está el cuello de botella? –

+0

Debe haber algunos lugares comunes (a los que acceden los subprocesos de procesamiento) con código de bloqueo/sincronización, ¿podría compartir este código de sincronización – sll

Respuesta

-1

Intente utilizar la biblioteca de tareas desde .net 4 (System.Threading.Task). Esta biblioteca tiene optimizaciones incorporadas para diferentes cantidades de procesadores.

no tienen ni idea de lo que es un problema, tal vez porque el fragmento de código no es muy informativo

+0

El uso de la librería Task no resolverá su problema, ya está usando Threads, que cuando se profundiza lo suficiente es lo que Tarea va a utilizar. –

+0

Gracias por la información, capt. Solo quería decir que la biblioteca de tareas tiene una programación y optimizaciones de conteo de hilos. Eso no es lo mismo que estás usando hilos ásperos. Que tengas un buen día –

6

Es posible que su problema no es la computación depende de la CPU, pero de E/S de la envolvente. No ayuda decir que la E/S de su disco "solo está al 10%". No estoy seguro de que ese contador de rendimiento exista.

La razón por la que se vuelve más lento al utilizar más subprocesos es porque esos subprocesos intentan llegar a sus respectivos archivos al mismo tiempo, mientras que el subsistema de discos tiene dificultades para tratar de acomodar todos los subprocesos diferentes. Usted ve, incluso con una tecnología moderna como SSD donde el tiempo de búsqueda es varios órdenes de magnitud más pequeño que con los discos duros tradicionales, todavía hay una penalización involucrada.

En su lugar, debe concluir que su problema está en el disco y un único hilo probablemente sea la forma más rápida de resolver su problema.

Se podría argumentar que podría utilizar técnicas asíncronas para procesar un bit que se ha leído, mientras que en el fondo se lee el siguiente bit, pero creo que verá muy poca mejora de rendimiento allí.

Tuve un problema similar no hace mucho tiempo en una pequeña herramienta donde quería calcular las firmas MD5 de todos los archivos en mi disco duro y encontré que la CPU es demasiado rápida en comparación con el sistema de almacenamiento y yo obtuve resultados similares tratando de obtener más rendimiento mediante el uso de más hilos.

El uso de la Biblioteca de tareas paralelas no solucionó este problema.

+1

Estoy de acuerdo con lo que dices, pero no entiendo por qué si el problema es el disco E/S, puedo procesar los archivos más rápido usando varios ejecutables en un único ejecutable con más subprocesos. Siento que probablemente estoy haciendo algo mal, pero no sé qué porque cada hilo funciona de manera independiente. – powlette

+0

¿Su proceso se acelera cuando no hace nada con lo que lee? Quizás debas inhabilitar esto y verificar el resultado. Supongo que parte del procesamiento que está haciendo tiene problemas de bloqueo, incluso si realmente no puede verlo todavía. –

+0

¿Cuánto más rápido es más rápido? ¿Estamos hablando de aumentos de rendimiento de uno o dos dígitos? –

2

En primer lugar en un cuadro de 24 núcleos, si utiliza solo 4 hilos, la mayor parte de la CPU que podría utilizar es del 16,7%, de modo que obtendrá un 60% de utilización, lo que es bastante bueno.

Es difícil saber si su programa está vinculado a E/S en este punto, supongo que es así. Necesita ejecutar un generador de perfiles en su proyecto y ver qué secciones de código su proyecto está gastando la mayor parte de su tiempo. Si está sentado en una operación de lectura/escritura, está vinculado a E/S.

Es posible utilizar alguna forma de bloqueo entre hilos. Eso haría que el programa reduzca la velocidad a medida que agregue más subprocesos, y sí, ejecutar un segundo proceso lo solucionaría, pero también lo haría arreglar su bloqueo.

Lo que todo se reduce a sin información de perfiles no podemos decir si usar un segundo proceso acelerará las cosas o hará las cosas más lentas, necesitamos saber si el programa está suspendido en una operación de E/S, un bloqueo operación, o simplemente tomar un largo tiempo en una función que se puede paralelizar mejor.

+1

Esta es una buena pregunta: parece que el póster es malo en matemáticas de primer nivel, y el resto de las otras personas tampoco. Aquí está la explicación: un hilo se ejecuta solo en un núcleo. Nunca. No se puede trabajar en 2 núcleos al mismo tiempo. Así que con el 100% de uso de 4 núcleos ... de 24 ... el nivel de uso os 4/24 = 16.7 máximo (+ un poco para el sistema operativo) de todos modos. Físicamente imposible obtener más. ¿Quieres 100%? Muévete a una máquina de 4 núcleos. – TomTom

+0

@TomTom Como puede leer en la pregunta, después de los 4 hilos, la aplicación realmente * pierde * el rendimiento. Además, en mi máquina 4 Core, el mismo comportamiento se experimenta cuando pongo más de 2 hilos en una tarea intensiva. Es obvio para mí que una aplicación tiene un intervalo de tiempo máximo asignado por el sistema operativo y todos sus hilos deben compartir este segmento de tiempo. – ThunderGr

+0

@ThunderGr Cada thread obtiene su propio timeslice, ese es el punto de un hilo.Una máquina de núcleo único puede ejecutar un intervalo de tiempo simultáneo, un núcleo duo puede ejecutar dos segmentos de tiempo concurrentes, ect ... El problema del póster es que el poder de procesamiento de la CPU no es su problema, su programa está esperando que el disco devuelva algún IO o algún recurso que tenga un bloqueo para ser liberado. Agregar más hilos aumenta la escasez de lo que sea que su programa se esté quedando corto y lo haga funcionar *** más lento *** –

0

Creo que averigua qué caché de archivos no es ideal en caso de que un proceso escriba datos en muchos archivos al mismo tiempo. La memoria caché de archivos debe sincronizarse con el disco cuando el número de caché de páginas sucias supera un umbral. Parece que los escritores simultáneos en un proceso alcanzan el umbral más rápido que el único escritor de subprocesos. Puede leer leer sobre la caché del sistema de archivos aquí File Cache Performance and Tuning