Domanda

Ho recentemente trasferito in C # .NET 4.

I Love Parallel.For, ma non è sicuro quando usare e quando non farlo. So che quando l'ordine non è importante per me - lo userò

.

Ma ci sono tutte le prove per quanto riguarda il sovraccarico di lavoro con Parallels? Che significa, se il mio ciclo viene eseguito solo 10 volte (ed esegue molto poco logici) - dovrei evitare di Parallels? Ci sono delle regole del pollice?

È stato utile?

Soluzione

Vorrei evitare di usare Parallel.For meno che le prestazioni è un problema.

La scrittura di codice che viene eseguito è contemporaneamente in generale più difficile che scrivere codice threaded singolo. Inoltre, se si commette un errore a causa di un problema di concorrenza può essere difficile eseguire il debug di esso. Per esempio il bug potrebbe avvenire solo a volte e non essere facilmente riproducibile. Se non avete un bisogno specifico per aumentare le prestazioni vorrei suggerire che si mantiene semplice e utilizzare un ciclo ordinario su un singolo thread.

Altri suggerimenti

Il loop Parallel.For utilizza ThreadPool per eseguire il lavoro in un ciclo richiamando un delegato una volta per ciascuna iterazione di un ciclo.

L'idea generale di come funziona Parallel.For possono essere presentati come segue:

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();
    }
}

Parallel.For ritorna ParallelLoopResult tipo di valore, che contiene i dettagli sul ciclo completato. Uno dei suoi sovraccarichi è la seguente:

public static ParallelLoopResult For(int fromInclusive, int toExclusive, Action<int> body);

E 'importante rendersi conto che l'esecuzione parallela non è sempre più veloce di esecuzione seriale. Per decidere se utilizzare parallelo o meno si deve stimare il carico di lavoro che farà ogni iterazione di un ciclo. Se il lavoro effettivo che vengono effettuate dal loop è piccola relativamente al costo sincronizzazione dei thread, è meglio usare ciclo normale.

Questa è una delle esempio quando seriale per le prestazioni ciclo è più veloce che in parallelo:

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;
}

Output:

0.0001963 sec.
0.0346729 sec.

Citando SQLite FAQ: ' Le discussioni sono il male . Evitare di loro '

Parallelizzazione è utile per performance. ottimizzazione delle prestazioni delle applicazioni è una delle cose più contro-intuitivo nella progettazione del software, e deve essere fatto con estrema cura, utilizzando gli strumenti di misurazione di destra, o sarà semplicemente guardare divertente.

Alcuni sarebbe ottimizzare il codice utente per rispondere in un microsecondo, invece di millisecondi, avendo chiaramente alcun valore e causando un sacco di danni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top