4

我有几个使用传统语法编写的循环

foreach(x in xs) {....}

其中一些循环在计算方面非常密集,我只是使用如下并行语法更改了它们:

Parallel.ForEach(x, xs => {...});

我看到性能大幅提升!!现在我的问题是:我是在使用并行多线程引入错误吗?我读到线程安全很复杂,并且会产生奇怪的错误;我应该担心什么?

4

2 回答 2

4

访问共享状态很可能不会产生预期的结果。简单的例子:

int sum = 0;
for (int i = 0; i < 1000000; i++)
{
    sum++;
}

将其更改为

Parallel.For(0, 1000000, i => { sum++; });

你会看到sum会有一些随机值,因为多个线程正在读/写sum

如果您锁定更新,您将解决问题,但您实际上会将操作再次转换为顺序操作。

您需要确保循环中发生的任何事情都是安全的。

Microsoft Patterns and Practices 写了一本书来解释所有这些以及更多内容。在简单地更改代码以使用并行循环之前,您应该检查一下。

于 2012-07-23T16:57:09.090 回答
2

可以肯定地说 - 发布您的迭代/循环代码。

但总的来说,您的迭代应该彼此独立,并尽量避免共享状态。跨并行迭代资源的任何共享资源都可能引入错误。

此外,当您的计算依赖于其他一些计算或并行操作或循环时,更好地使用 TPL 任务链,它还有助于避免共享跨线程资源。

更多信息和示例以及模式/反模式在免费的 Microsoft 书籍中得到了很好的描述:并行编程模式:使用 .NET Framework 4 理解和应用并行模式

在这里下载

http://www.microsoft.com/en-us/download/details.aspx?id=19222

于 2012-07-23T16:51:55.817 回答