I am using VB.net to write a parallel based code. I use Parallel.For to generate pairs of 500 objects or in combination C(500,2) such as the following code; but I found that it didn’t always generate all combinations which should be 124750 (shown from variable Counter). No other thread was runing when this code was run. I am using a Win-7 32 Bit desktop with Intel Core i5 CPU [email protected], 3.33 GHz and RAM 2GB. What’s wrong with the code and how to solve this problem? Thank You.
Dim Counter As Integer = 0
Parallel.For(0, 499, Sub(i)
For j As Integer = i + 1 To 499
Counter += 1
Console.Write(i & ":" & j)
Next
End Sub)
Console.Writeline("Iteration number: " & Counter)
It is not that all were not generated, is it that the counter got broken. You encountered classic read/write race condition.
You should use atomic increment to solve the problem.
Also, printing is really slow and locks internally. So you are not going to gain any performance using parallelism this way.
But, this is basic knowledge. You should not, under any scenario, try to parallelize your code if you don’t have this knowledge.
Parallel.For uses a thread pool to process your loop. As soon as one of its threads is free, it assigns it to the next element.
It’s a common problem : calling something like count++ on a shared variable from multiple threads.
- Thread #1 reads the value of count.
- Thread #2 reads the value of count.
- Thread #1 increments its local copy.
- Thread #2 increments its local copy.
- Thread #1 writes the incremented value back to count.
- Thread #2 writes the incremented value back to count.
This way, the value written by thread #1 is overwritten by thread #2, so the value is actually incremented only once.
What you need to do is to “lock” count++ or use Interlocked class.
lock (lockObject)
{
Counter += 1
}
thanks for all responds and now I have the answer.
Dim total As Integer = 0
Dim numbers() = Enumerable.Range(1, 500).ToArray
Parallel.For(Of Integer)(0, numbers.Length, Function() 0,
Function(j, [loop], subtotal)
For k = j + 1 To numbers.Count - 1
subtotal += 1
Next
Return subtotal
End Function,
Function(x) Interlocked.Add(total, x))
1