Parallel.for in c# is not working

Go To StackoverFlow.com

0

I wrote Wpf code to generate normal distribution using random variable.

using System.Threading.Tasks;
using System.Threading;


private void Button_Click(object sender, RoutedEventArgs e)
        {            .....


for (int t = 0; t < normalx.Count; t++)
            {
                normaly.Insert(t, (2 / ((Math.Pow(2 * Math.PI, 0.5)) * rmsnormalvalue)) * Math.Exp(-0.5 * Math.Pow(standardnormalx.ElementAt(t), 2)));
            }

...


}

this is sequantial codes.

To run as a parallel thread, I changed this to

Parallel.For(0, normalx.Count, t =>
            {
                normaly.Insert(t, (2 / ((Math.Pow(2 * Math.PI, 0.5)) * rmsnormalvalue)) * Math.Exp(-0.5 * Math.Pow(standardnormalx.ElementAt(t), 2)));
            });

but build is ok, but in run-time only one thread region(normalx.Count/8 <- my pc is i7)

was worked and compuated.

What's the wrong?

2012-04-04 06:31
by Lee
What is normaly and is it thread-safe - Henk Holterman 2012-04-04 06:38


1

The TPL does not guarantee that it will use a given number of threads for a parallel loop. It is ABLE to, but it may determine that the overhead of starting additional threads is too much given the amount of work to be done within the loop and just run on a single thread.

http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.for.aspx

Executes a for loop in which iterations may run in parallel.

(emphasis mine)

You may be able to force multiple threads (not that forcing is necessarily a good idea) by providing a custom partitioner, but I have not tried that yet

http://msdn.microsoft.com/en-us/library/dd560853.aspx

The TPL is still free to say "nice that you provided a custom partitioner, but I'm still going to execute each partition sequentially on one thread". I don't know how the current implementation behaves in that regard.

UPDATE

Re-reading and checking Henk's comment, I'm not sure I read your question correctly the first time.

Are you saying that only some of the normals have been computed? If that is the case, it could be because whatever collection is backing normaly is not thread-safe.

If that is the case, you could do your calculation, assign it to a temporary variable, then use a lock around the actual insert. That would create a bottleneck inserting into the collection, but you would still gain parallelism for the calculation.

2012-04-04 06:34
by Eric J.
Would that change the region of the input/output - Henk Holterman 2012-04-04 06:40
@Henk: I may have misunderstood the question. Updated my answer - Eric J. 2012-04-04 06:47


0

It is almost certainly the case that normaly.Insert(t, ...) is not thread-safe, nor is it likely to be the operation you want to perform. What you want to do is create a blank datastructure ahead of time with all the slots you'll need, then fill them in with your parallel loop. Here's how you might do it:

var temp = new double[normalx.Count];
Parallel.For(0, normalx.Count, t =>
    temp[t] = 2 / ((Math.Pow(2 * Math.PI, 0.5)) * rmsnormalvalue)) *
              Math.Exp(-0.5 * Math.Pow(standardnormalx.ElementAt(t), 2));
normaly = temp.ToList();
2012-04-04 06:54
by Gabe
Ads