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?
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.
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();
normaly
and is it thread-safe - Henk Holterman 2012-04-04 06:38