¿Qué hace MaxDegreeOfParallelism?


Estoy usando Paralelo.ForEach y yo estamos haciendo algunas actualizaciones de la base de datos, ahora sin establecer MaxDegreeOfParallelism , una máquina de procesador de doble núcleo resulta en tiempos de espera del cliente sql, donde la máquina de procesador de cuatro núcleos de alguna manera no se agota el tiempo.

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 MaxDegreeOfParallelism que probablemente ejecutarán menos operaciones simultáneamente y no resultarán en ¿tiempos de espera?

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

Ok He leído todos los otros mensajes y MSDN también, pero será configurar MaxDegreeOfParallelism a menor valor hacer que mis máquinas quad core sufren?

Por ejemplo, hay de todos modos para hacer algo como, si la CPU tiene dos núcleos, a continuación, utilizar 20, si la CPU tiene cuatro núcleos a continuación, 40?

4 answers

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

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

Para averiguar esto, escribí esta pieza de código de prueba. Hay una cerradura artificial allí para estimular el TPL para utilizar 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 consola muestra que hasta 8 tareas se están ejecutando al mismo tiempo. Así:

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 está tratando de ejecutar 8 al mismo tiempo.

Si lo limito a algún 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 es en una máquina quadcore.

 59
Author: Gennady Vanin Геннадий Ванин,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-15 10:16:38

Por ejemplo, hay de todos modos para hacer algo como, si la CPU tiene dos núcleos, a continuación, utilizar 20, si la CPU tiene cuatro núcleos a continuación, 40?

Puede hacer esto para hacer que el paralelismo dependa del número 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 usar hyper-threading para simular núcleos adicionales. Así que si usted tiene un procesador de cuatro núcleos, entonces Environment.ProcessorCount probablemente reportará esto como 8 núcleos. He encontrado que si se establece el paralelismo para dar cuenta de los núcleos simulados, entonces en realidad ralentiza otros subprocesos, como los subprocesos de interfaz de usuario.

Así que aunque la operación terminará un poco más rápido, una interfaz de usuario de la aplicación puede experimentar un retraso significativo durante este tiempo. Dividiendo el medio Ambiente.ProcessorCount ' by 2 parece alcanzar las mismas velocidades de procesamiento mientras mantiene la CPU disponible para los subprocesos de interfaz de usuario.

 14
Author: bugged87,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-26 15:00:04

Parece que el código que estás ejecutando en paralelo está bloqueado, lo que significa que a menos que puedas encontrar y solucionar el problema que está causando eso, no deberías paralelizarlo en absoluto.

 1
Author: jimrandomh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-02 18:31:31

Establece el número de subprocesos que se ejecutarán en paralelo...

 -1
Author: SolidSnake,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-02 18:29:00