0

我编写了 Wpf 代码来使用随机变量生成正态分布。

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)));
            }

...


}

这是连续代码。

要作为并行线程运行,我将其更改为

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)));
            });

但是构建没问题,但是在运行时只有一个线程区域(normalx.Count/8<-我的电脑是i7)

工作和计算。

怎么了?

4

2 回答 2

2

TPL 不保证它将使用给定数量的线程进行并行循环。可以,但是考虑到要在循环内完成的工作量并且只在单个线程上运行,它可能会确定启动额外线程的开销太大。

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

执行一个 for 循环,其中迭代可以并行运行。

(强调我的)

可以通过提供自定义分区器来强制多个线程(不是强制是一个好主意),但我还没有尝试过

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

TPL 仍然可以说“很高兴您提供了自定义分区程序,但我仍将在一个线程上按顺序执行每个分区”。我不知道当前的实现在这方面的表现如何。

更新

重新阅读并检查 Henk 的评论,我不确定我第一次是否正确阅读了您的问题。

你是说只计算了一些法线?如果是这种情况,可能是因为支持normaly的任何集合都不是线程安全的。

如果是这种情况,您可以进行计算,将其分配给临时变量,然后lock在实际插入周围使用 a。这会造成插入集合的瓶颈,但您仍然可以获得计算的并行性。

于 2012-04-04T06:34:46.923 回答
0

几乎可以肯定,这种情况normaly.Insert(t, ...)不是线程安全的,也不太可能是您想要执行的操作。您要做的是提前创建一个空白数据结构,其中包含您需要的所有插槽,然后用您的并行循环填充它们。您可以这样做:

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-04T06:54:15.013 回答