2

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 650@3.2GHz, 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)
7

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.

| improve this answer | |
1

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
}
| improve this answer | |
0

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))
| improve this answer | |
  • You are supposed to accept (that green check icon under vote count) an answer and edit your question if you want to tell how you fixed your problem. – Euphoric Nov 25 '13 at 9:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.