# How can we be sure that the number of iterations of commands in "Parallel.For" matches the number of iterations that were set for it?

331 Reputation points
2022-12-14T03:49:58.633+00:00

Hi guys,
In my article, I want to compare the speed of sequential processing to parallel processing in various conditions, so in one example, I want to convert the following sequential command to parallel, but after converting it to parallel, it seems that the loop is not repeated for the specified number of times. It may be necessary to use Concurrent Collection or a `lock` statement, but this usually reduces the speed of parallel processing compared to sequential processing.
According to what was said, is there a solution or approach to converting the following code so that the performance does not drop and the number of times the loop is executed is complete so that it can be displayed?

``````        static long Counter = 0;
public static long Calculate()
{
int Total = 0;
for (int i = 0; i < 30; i++)
{
Total = 20 / 4;
Total = 20 * 4;
Total = 20 ^ 4;
Total = 20 - 4;
Total = 20 % 4;
}
Counter += 30;
return Counter;
}
``````

`Sequential`:

``````        static void Main(string[] args)
{
Stopwatch SW = new Stopwatch();
SW.Start();
for (int i = 0; i < 50000000; i++)
{
Calculate();
Calculate();
Calculate();
Calculate();
Calculate();
}
SW.Stop();
Console.WriteLine("Total seconds: " + SW.Elapsed.TotalSeconds + ", Counter: " + Counter);
}
``````

Result:

`Counter` value=50000000*30*5=7,500,000,000

`Parallel`:

``````        static void Main(string[] args)
{
Stopwatch SW = new Stopwatch();
SW.Start();
Parallel.For(0, 50000000, (int i) =>
{
Calculate();
Calculate();
Calculate();
Calculate();
Calculate();
});
SW.Stop();
Console.WriteLine("Total seconds: " + SW.Elapsed.TotalSeconds + ", Counter: " + Counter);
}
``````

One of the results:

`Counter` value=50000000*30*5= different values are displayed

I use the following tools:

• .NET Framework 4.5
• Console app
• Windows 7

Best regards

.NET CLI
.NET CLI
A cross-platform toolchain for developing, building, running, and publishing .NET applications.
330 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,703 questions

1. 62,141 Reputation points
2022-12-16T20:04:35.247+00:00

your calculate routine is too fast. it is quicker than the overhead of managing the parallel processing, so sequential is typically faster. you need to make the calculate take longer. also do not use the debugger, as it will affect the parallel process performance.

``````using System.Diagnostics;

const int LOOP_COUNT = 10000;

Console.WriteLine(\$"Call Calulate {LOOP_COUNT} times" );
SequentialCalcute();
ParallelCalcute();

long Calcute()
{
int Total = 0;
for (int i = 0; i < 10000; i++) // add more iteration to make parallel faster than sequential
{
Total = 20 / 4;
Total = 20 * 4;
Total = 20 ^ 4;
Total = 20 - 4;
Total = 20 % 4;
}
}

void SequentialCalcute()
{
var Counter = 0;
Stopwatch SW = new Stopwatch();
SW.Start();
for (int i = 0; i < LOOP_COUNT; i++)
{
Calcute();
++Counter;
}
SW.Stop();
Console.WriteLine("Sequential Total seconds: " + SW.Elapsed.TotalSeconds + ", Counter: " + Counter);
}

void ParallelCalcute()
{
var Counter = 0;
Stopwatch SW = new Stopwatch();
SW.Start();
Parallel.For(0, LOOP_COUNT, i =>
{
Calcute();
});
SW.Stop();
Console.WriteLine("Parallel Total seconds: " + SW.Elapsed.TotalSeconds + ", Counter: " + Counter);
}

``````

Update:

1. 43,376 Reputation points Microsoft Vendor
2022-12-14T09:18:55.383+00:00

Hi @Reza Jaferi ,

Variables are shared among multiple threads. This means that multiple threads can read and write to this variable concurrently, which may cause race conditions and other unpredictable behavior.

For example, when multiple threads try to increment a variable at the same time, the resulting value might not be what you expect.

If you want it to explicitly show the expected number, then you have to use a lock, which of course incurs additional performance overhead.

Below is the modification using lock:

``````static long Counter = 0;
private static object _lock = new object();

public static long Calculate()
{
int Total = 0;
for (int i = 0; i < 30; i++)
{
Total = 20 / 4;
Total = 20 * 4;
Total = 20 ^ 4;
Total = 20 - 4;
Total = 20 % 4;
}

// Use a lock statement
lock (_lock)
{
Counter += 30;
}

return Counter;
}
``````

Update：

As mentioned, the parallel approach doesn't affect how many times you should run it, but you have to understand when to use parallelism.

If overlapping of data occurs, you must secure the data with a lock or something similar.

If your data does not overlap, like the addition of 100 random numbers, you can get the performance improvement you expect by using parallelism.

Parallelism does not exist in this code to improve what you expect, I hope you could understand.

This method will run the specified number of times, you don't need to worry about it.

Best Regards,
Jiale