Domanda

C'è il supporto integrato in TPL (Task-Parallel-Library) per le operazioni di dosaggio?

Recentemente sono stato a giocare con una routine per effettuare la sostituzione dei caratteri su un array di caratteri utilizzando una tabella di ricerca vale a dire traslitterazione:

for (int i = 0; i < chars.Length; i++)
{
    char replaceChar;

    if (lookup.TryGetValue(chars[i], out replaceChar))
    {
        chars[i] = replaceChar;
    }
}

ho potuto vedere che questo potrebbe essere banalmente parallelizzati, così saltato con un primo tentativo che sapevo effettuerebbe peggio, come i compiti sono stati troppo a grana fine:

Parallel.For(0, chars.Length, i =>
{
    char replaceChar;

    if (lookup.TryGetValue(chars[i], out replaceChar))
    {
        chars[i] = replaceChar;
    }
});

Ho poi rielaborato l'algoritmo per uso dosaggio in modo che il lavoro potrebbe essere chunked su diversi thread in meno lotti a grana fine. Questo uso di fili come previsto e ho avuto un po 'vicino alla velocità lineare fino.

Sono sicuro che ci deve essere costruito il supporto integrato per il dosaggio nel TPL. Qual è la sintassi, e come si usa?

const int CharBatch = 100;
int charLen = chars.Length;

Parallel.For(0, ((charLen / CharBatch) + 1), i =>
{
    int batchUpper = ((i + 1) * CharBatch);

    for (int j = i * CharBatch; j < batchUpper && j < charLen; j++)
    {
        char replaceChar;

        if (lookup.TryGetValue(chars[j], out replaceChar))
        {
            chars[j] = replaceChar;
        }
    }
});

Aggiorna

Dopo aver usato @ risposta di Oliver e la sua sostituzione con un Parallel.For Parallel.ForEach e partizionamento il codice è il seguente:

const int CharBatch = 100;

Parallel.ForEach(Partitioner.Create(0, chars.Length, CharBatch), range =>
{
    for (int i = range.Item1; i < range.Item2; i++)
    {
        char replaceChar;

        if (lookup.TryGetValue(chars[i], out replaceChar))
        {
            chars[i] = replaceChar;
        }
    }
});
È stato utile?

Soluzione

Per una migliore ottenere la vostra testa intorno si dovrebbe ottenere il modelli per la programmazione parallela: comprensione e l'applicazione Patterns parallelo con il .NET Framework 4 . E 'una grande fonte e spiega i modi comuni su come utilizzare il TPL.

Date un'occhiata a pagina 26 (molto piccoli corpi di loop). Ci troverete questo esempio:

Parallel.ForEach(Partitioner.Create(from, to), range =>
{
    for (int i = range.Item1; i < range.Item2; i++)
    {
        // ... process i
    }
});

Così il pezzo mancante si sta cercando è la System.Concurrent.Collections.Partitioner .

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