2012-01-19 11 views
20

Hoy probé hacer alguna optimización a la declaración foreach, que funciona en XDocument.¿Por qué Parallel.ForEach no está ejecutando varios subprocesos?

Antes de optimización:

foreach (XElement elem in xDoc.Descendants("APSEvent").ToList()) 
{ 
    //some operations 
} 

Después de la optimización:

Parallel.ForEach(xDoc.Descendants("APSEvent").ToList(), elem => 
{ 
    //same operations 
}); 

vi que en .NET Parallel.ForEach(...) abrió sólo un hilo! Como resultado, el intervalo de tiempo de Parallel fue mayor que el estándar foreach.

¿Por qué crees que .NET solo abrió 1 hilo? Debido al bloqueo de archivo? Gracias

+10

¿Cuántos núcleos o procesadores lógicos tiene en su máquina? ¿Cuántos elementos hay en la lista? –

+0

No puedo ver ninguna relación del título con la pregunta. –

+0

Christian.K, tengo servidor con procesador Xeon y ram 8GB (Dell PowerEdge R210) con sistema operativo MS Server2008. Creo que no depende de la cantidad de elementos que tengo en el documento XML, creo que la penalización de tiempo se debe al bloqueo de archivos. – zzfima

Respuesta

14

Es por diseño que Parallel.ForEach puede utilizar un menor número de hilos que el solicitado para lograr un mejor rendimiento. De acuerdo con MSDN [link]:

Por defecto, los métodos y Parallel.ForEach Parallel.For puede utilizar un número variable de tareas. Es por eso que, por ejemplo, la clase ParallelOptions tiene una propiedad MaxDegreeOfParallelism en lugar de una propiedad "MinDegreeOfParallelism". La idea es que el sistema puede usar menos hilos de los solicitados para procesar un bucle.

El grupo de subprocesos de .NET se adapta dinámicamente a cargas de trabajo cambiantes al permitir que el número de subprocesos de trabajo para tareas paralelas cambie con el tiempo. En tiempo de ejecución, el sistema observa si aumentar el número de subprocesos mejora o degrada el rendimiento general y ajusta el número de subprocesos de trabajo en consecuencia.

0

Sí exactamente, Document.Load(...)locks the file y debido a los recursos contención entre hilos, TPL es incapaz de utilizar el poder de múltiples hilos. Intente cargar el XML en un Stream y luego use Parallel.For(...).

+6

Eso solo explicaría por qué solo un hilo _hace progreso_, no por qué solo un hilo es _created_ - como afirma el OP. 'Parallel.ForEach' no puede (sensiblemente) tener ningún conocimiento sobre la colección que está iterando (solo" ve "que se pasa una 'Lista ' y no es razonable suponer que tenga una implementación especial para eso). Además, 'ToList' básicamente recupera todos los elementos con entusiasmo, por lo que el bloqueo (y el hecho de que se lea desde un archivo) no deberían hacer ninguna diferencia aquí. –

-1

¿Tiene un solo procesador? TPL puede limitar el número de hilos a uno en este caso. Lo mismo puede suceder si la colección es muy pequeña. Pruebe una colección más grande. Consulte this answer para obtener más información sobre cómo se determina el grado de paralelismo.

+2

Broma de una respuesta. Probablemente apropiado como un comentario. – Mukus

1

utilizar de esta manera:

int ParallelThreads = 10; 
Parallel.ForEach(xDoc.Descendants("APSEvent").ToList(), new ParallelOptions() { MaxDegreeOfParallelism = ParallelThreads }, (myXDOC, i, j) => 
{ 
//do whatever you want here 
}); 
+0

Solo tenga en cuenta que MaxDegreeOfParallelism establece la cantidad máxima de hilos, no el mínimo. Por lo tanto, es útil cuando quiere limitar o disminuir la cantidad de hilos/núcleos que se utilizan. – coloboxp

1

De la descripción del problema, no hay nada que explique por qué el TPL no está generando más hilos.

No hay evidencia en la pregunta que sea siquiera el problema. Eso se puede solucionar con bastante facilidad: puede registrar la id. Del subproceso, antes de ingresar al bucle, y como lo primero que hace dentro del ciclo.

Si siempre es el mismo número, es el TPL que falla al generar subprocesos. A continuación, debe probar diferentes versiones de su código y qué cambio activa el TPL para serializar todo. Una razón podría ser si hay una pequeña cantidad de elementos en su lista.El TPL divide su colección, y si tiene solo algunos elementos, puede terminar con un solo lote. Este comportamiento es configurable por cierto.

Podría estar inadvertidamente teniendo un bloqueo en el circuito, entonces verá muchos números diferentes, pero no hay aceleración. Luego, simplifique el código hasta que el problema desaparezca.

Cuestiones relacionadas