La boucle Parallel.For utilise ThreadPool pour exécuter le travail dans une boucle en invoquant un délégué une fois pour chaque itération d'une boucle.
L'idée générale de la façon dont fonctionne Parallel.For peut être présenté comme suit:
public static void MyParallelFor(int inclusiveLowerBound, int exclusiveUpperBound, Action<int> body)
{
// Get the number of processors, initialize the number of remaining
// threads, and set the starting point for the iteration.
int numProcs = Environment.ProcessorCount;
int remainingWorkItems = numProcs;
int nextIteration = inclusiveLowerBound;
using (ManualResetEvent mre = new ManualResetEvent(false))
{
// Create each of the work items.
for (int p = 0; p < numProcs; p++)
{
ThreadPool.QueueUserWorkItem(delegate
{
int index;
while ((index = Interlocked.Increment(ref nextIteration) - 1) < exclusiveUpperBound)
body(index);
if (Interlocked.Decrement(ref remainingWorkItems) == 0)
mre.Set();
});
}
// Wait for all threads to complete.
mre.WaitOne();
}
}
retourne Parallel.For type de valeur ParallelLoopResult, qui contient des détails sur la boucle terminée. L'un de ses surcharges est la suivante:
public static ParallelLoopResult For(int fromInclusive, int toExclusive, Action<int> body);
Il est important de réaliser que l'exécution parallèle n'est pas toujours plus rapide que l'exécution en série. Pour décider d'utiliser parallèlement ou non, vous devez estimer la charge de travail qui va faire par itération d'une boucle. Si le travail réel effectué par la boucle est faible par rapport au coût de la synchronisation des threads, il est préférable d'utiliser une boucle ordinaire.
Ceci est un exemple en série pour des performances en boucle est plus rapide que parallèle:
static void Main(string[] args)
{
Action<int> action = new Action<int>(SimpleMethod);
// ordinary For loop performance estimation
var sw = Stopwatch.StartNew();
for(int i = 0; i < 1000; i++)
action(i);
Console.WriteLine("{0} sec.", sw.Elapsed.TotalSeconds);
// parallel For loop performance estimation
sw = Stopwatch.StartNew();
Parallel.For(0, 1000, action);
Console.WriteLine("{0} sec.", sw.Elapsed.TotalSeconds);
}
static void SimpleMethod(int index)
{
int d = 1;
int result = index/d;
}
Sortie:
0.0001963 sec.
0.0346729 sec.
Voici un très bon ebook gratuit de Microsoft qui couvre ce sujet " [Patterns pour la programmation parallèle: Comprendre et appliquer des modèles parallèles avec le .NET Framework 4] (https://www.microsoft.com/en-us/download/details.aspx?id=19222) " –