c# .net-4.0 task-parallel-library parallel-extensions parallel.foreach

c# - ¿Qué hace MaxDegreeOfParallelism?



.net-4.0 task-parallel-library (4)

Por ejemplo, ¿hay alguna forma de hacer algo como, si la CPU tiene dos núcleos, luego usa 20, si la CPU tiene cuatro núcleos, entonces 40?

Puede hacer esto para que el paralelismo dependa de la cantidad de núcleos de CPU:

var options = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount * 10 }; Parallel.ForEach(sourceCollection, options, sourceItem => { // do something });

Sin embargo, las CPU más nuevas tienden a utilizar hyper-threading para simular núcleos extra. Entonces, si tiene un procesador de cuatro núcleos, entonces Environment.ProcessorCount probablemente reportará esto como 8 núcleos. Descubrí que si establece el paralelismo para tener en cuenta los núcleos simulados, en realidad ralentizará otros subprocesos, como los subprocesos de interfaz de usuario.

Entonces, aunque la operación terminará un poco más rápido, una IU de la aplicación puede experimentar un retraso significativo durante este tiempo. Dividir el `Environment.ProcessorCount ''por 2 parece lograr las mismas velocidades de procesamiento mientras se mantiene la CPU disponible para los subprocesos de la interfaz de usuario.

Estoy usando Parallel.ForEach y estoy haciendo algunas actualizaciones de la base de datos, ahora sin configurar MaxDegreeOfParallelism, una máquina procesadora de doble núcleo da como resultado tiempos de espera de cliente de SQL, mientras que otra máquina procesadora de cuatro núcleos no tiene tiempo de espera.

Ahora no tengo control sobre qué tipo de núcleos de procesador están disponibles donde se ejecuta mi código, ¿pero hay algunas configuraciones que puedo cambiar con MaxDegreeOfParalelismo que probablemente ejecutará menos operaciones simultáneamente y no dará como resultado tiempos de espera?

Puedo aumentar los tiempos de espera, pero no es una buena solución, si con una CPU más baja puedo procesar menos operaciones simultáneamente, eso supondrá una carga menor para la CPU.

Ok, he leído todas las demás publicaciones y MSDN también, pero ¿establecerá MaxDegreeOfPalallelism en un valor inferior hará que mis máquinas de cuatro núcleos sufran?

Por ejemplo, ¿hay alguna forma de hacer algo como, si la CPU tiene dos núcleos, luego usa 20, si la CPU tiene cuatro núcleos, entonces 40?


La respuesta es que es el límite superior para toda la operación paralela, independientemente del número de núcleos.

Entonces, incluso si no usa la CPU porque está esperando IO o un bloqueo, no se ejecutarán tareas adicionales en paralelo, solo el máximo que especifique.

Para averiguarlo, escribí esta pieza de código de prueba. Hay un bloqueo artificial allí para estimular el TPL a usar más hilos. Lo mismo sucederá cuando su código esté esperando IO o base de datos.

class Program { static void Main(string[] args) { var locker = new Object(); int count = 0; Parallel.For (0 , 1000 , new ParallelOptions { MaxDegreeOfParallelism = 2 } , (i) => { Interlocked.Increment(ref count); lock (locker) { Console.WriteLine("Number of active threads:" + count); Thread.Sleep(10); } Interlocked.Decrement(ref count); } ); } }

Si no especifico MaxDegreeOfParallelism, el registro de la consola muestra que se están ejecutando hasta 8 tareas al mismo tiempo. Me gusta esto:

Number of active threads:6 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:6 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:7

Comienza más bajo, aumenta con el tiempo y al final intenta ejecutar 8 al mismo tiempo.

Si lo limito a un valor arbitrario (digamos 2), obtengo

Number of active threads:2 Number of active threads:1 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2

Oh, y esto está en una máquina de cuatro puntos.


Parece que el código que está ejecutando en paralelo está bloqueado, lo que significa que a menos que pueda encontrar y solucionar el problema que lo está causando, no debe paralelizarlo en absoluto.


establece el número de hilos para ejecutar en paralelo ...