Understanding Parallel.For Loop and local variables

Marco Teixeira

I am new in the parallel computing and I'm with some problems running a Parallel.For in C#. I'm tryng visit multiple Web Sites in simultaneous, get the HTML and register them in multiple SQLite Database. Everything seems work fine until I check the results more precisely. I noticed that in one loop for 0 to 20, the code entered 20 times in the shared part of loop and only 16 times in local part. So, was missing 4 results. To understand the problem I made a experience where i only put two counters. One in the global part and another in the local. The output of global count was 20 and in the local part 1! After that i put a 2 seconds sleep before the returning of global part to the local part. In this case the output of global count was 20 and in the local part was 13! Can you explain me what I'm doing wrong?

static void ParalellCalc()
        {
            var tm = new Stopwatch();
            tm.Start();
            int count = 0;
            int count2 = 0;
            var parl = Parallel.For<int>(0, 20, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount}, () => 0, (i, state, Enrada) =>
            {
                count++;
                Thread.Sleep(2000);
                return Enrada;
            },
            (x) =>
            {
                count2++;
            }
            );

            tm.Stop();
            Console.WriteLine(tm.Elapsed);
            Console.WriteLine("Global: " + count.ToString());
            Console.WriteLine("Local: " + count2.ToString());
            Console.WriteLine(tm.Elapsed);
            tm.Reset();
        }

EDIT: I go into your suggestions and i made the same example with the Interlocked.Increment to increment the counters. The produced results are exacly the same. If I remove the Thread.Sleep(2000) the second counter produce the result of 1!? If i don't remove produce the result of 16. The first counter display in all the cases the value of 20 as should be. Anyone can explain that?

static void ParalellCalc()
        {
            var tm = new Stopwatch();
            tm.Start();
            int count = 0;
            int count2 = 0;
            var parl = Parallel.For<int>(0, 20, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount}, () => 0, (i, state, Enrada) =>
            {
                Interlocked.Increment(ref count);
                return Enrada;
            },
            (x) =>
            {
                Interlocked.Increment(ref count2);
            });

            tm.Stop();
            Console.WriteLine(tm.Elapsed);
            Console.WriteLine("Global: " + count.ToString());
            Console.WriteLine("Local: " + count2.ToString());
            Console.WriteLine(tm.Elapsed);
            tm.Reset();
        } 
Theodor Zoulias

The Parallel.For method parallelizes the workload by splitting it into partitions. The number of partitions and the size of each partition is determined by internal heuristics. Your experiment demonstrates that a workload of 20 items can be split in only 1 partition, or in 16 partitions, depending in the duration of the processing of each item. By adding the line Thread.Sleep(2000) you are changing your workload from extremely light to quite heavy, and so more partitions are created to balance the workload. These 16 partitions are typically processed by fewer than 16 threads, because each thread processes more than one partitions.

For a better understanding of how Parallel.For works you should log more info than the two counters count and count2. You should also have one counter for each thread, using a ConcurrentDictionary<int, int> with keys the ID of each thread.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Local variables in parallel Jenkinsfile task

understanding local variables, closures and iterators

Can I use local variables inside a Parallel Foreach loop (without unintentionally rewriting the previous value)

Ipython parallel scripts running and return the local variables

decorator: understanding why it does not flush local variables

Local variables defined inside loop

How to print local variables of an OpenMP parallel region in gdb?

Parallel.ForEach with Dictionary and multiple local variables in C#

Selenium c# loop through local variables

syntax in for-loop using local variables

If program exits loop by goto are local variables deleted?

flushing thread local buffer at end of parallel loop with TBB

C# Parallel loop local variable thread safe Information

Understanding the output using local and global variables of same name

Python how to loop multiple variables and different steps parallel?

CUDA: Understanding the behavior of variables in the registers file in a loop with a dot product example

Understanding parallel thread execution

Understanding the for loop

Does the Java compiler optimize the creation of loop-local variables?

How do I solve local referenced variables inside a for loop?

Between iterations of the same loop, are local variables reused or reallocated?

ranged for loop of variables results in returning address-reference of local variable?

Toggle all Local Variables in *ngFor From Outside Loop

How to use a Func or Action in a loop instead of local variables?

How to expand two local variables inside a for loop in a batch file

How to correctly assign local variables to a for-loop in python?

local variables overwrite in function run multiple times in a loop

Stata: Generating variables in a loop using tuples local macro

Nested parallel for loop: "Parallel outer for loop" in "parallel inner for loop as a function"