MSDN > Home page del forum > Parallel Extensions to the .NET Framework > How to combine Thread-local variables and speed up small loop bodies?
Formula una domandaFormula una domanda
 

Con rispostaHow to combine Thread-local variables and speed up small loop bodies?

  • domenica 14 giugno 2009 17.16mistalan Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     Contiene codice
    Hi,

    I was trying to combine the two How-To´s from msdn:
    Speed Up Small Loop Bodies
    Write a Parallel.For Loop with Thread-Local Variables

    The example with the parallel thread-local variables was slower then the corresponding sequential implementation.
    So I want to create partitions based on the cpu count and parallelize just this (like the first example).

    Of course the following code isn´t correct because the variable "total" isn´t summed up thread-safe:

     private static IEnumerable<Tuple<int, int>> CreateRanges(int fromInclusive, int toExclusive)
        {
            // argument checking omitted
            int rangeSize = (toExclusive - fromInclusive) / System.Environment.ProcessorCount;
            for (int i = fromInclusive; i < toExclusive; i += rangeSize)
            {
                int from = i, to = Math.Min(i + rangeSize, toExclusive);
                yield return Tuple.Create(from, to);
            }
        }
    
        static void Main()
        {
            int[] arr2 = Enumerable.Range(0, 1000000).ToArray();
            long total = 0;
            Parallel.ForEach(CreateRanges(0, arr2.Length), range =>
            {
                for (int i = range.Item1; i < range.Item2; i++)
                {
                    // Small body.
                    total += arr2[i];
                }
            });
    
            Console.WriteLine(total);
            Console.ReadKey();
        }
    
    But I am really stuck cause I don´t have a glue how to parallelize the partitions and get the correct results.
    Can anybode help me?

    Thanks,
    Alex

Risposte

  • domenica 14 giugno 2009 20.09Miha MarkicMVPMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     Con rispostaContiene codice
    ForEach like this might do the job:

     Parallel.ForEach <Tuple<int, int>, long>(CreateRanges(0, arr2.Length),
                    () => 0,
                    (range, loop, subtotal) =>
                    {
                        for (int i = range.Item1; i < range.Item2; i++)
                        {
                            // Small body.
                            subtotal += arr2[i];
                        }
                        return subtotal;
                    },
                    subtotal => Interlocked.Add(ref total, subtotal));
    


    Miha Markic [MVP C#] http://blog.rthand.com

Tutte le risposte

  • domenica 14 giugno 2009 20.09Miha MarkicMVPMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     Con rispostaContiene codice
    ForEach like this might do the job:

     Parallel.ForEach <Tuple<int, int>, long>(CreateRanges(0, arr2.Length),
                    () => 0,
                    (range, loop, subtotal) =>
                    {
                        for (int i = range.Item1; i < range.Item2; i++)
                        {
                            // Small body.
                            subtotal += arr2[i];
                        }
                        return subtotal;
                    },
                    subtotal => Interlocked.Add(ref total, subtotal));
    


    Miha Markic [MVP C#] http://blog.rthand.com