我有几个使用传统语法编写的循环
foreach(x in xs) {....}
其中一些循环在计算方面相当密集,我只是使用如下的并行语法对它们进行了更改:
Parallel.ForEach(x, xs => {...});
我看到性能有了很大的提高!现在我的问题是:我是否引入了使用并行多线程的bug?我读到线程安全是复杂的,可能会产生奇怪的bug;我应该关注什么?
发布于 2012-07-23 16:57:09
访问共享状态很可能不会产生期望的结果。简单的例子:
int sum = 0;
for (int i = 0; i < 1000000; i++)
{
sum++;
}
将其更改为
Parallel.For(0, 1000000, i => { sum++; });
你会看到sum
会有一些随机值,因为多线程正在读/写sum
。
如果锁定更新,就可以解决问题,但本质上会再次将操作转换为顺序操作。
您需要确保循环中发生的任何事情都是安全的。
微软的模式和实践做了a book,解释了这一切甚至更多。在简单地将代码更改为使用并行循环之前,您应该先检查一下。
发布于 2012-07-23 16:51:56
确切地说--发布你的迭代/循环代码。
但总的来说,您的迭代应该彼此独立,并尽量避免共享状态。任何与并行迭代资源交叉的共享资源都可能引入bug。
此外,当您的计算依赖于一些其他计算或并行操作或循环时,最好使用TPL任务链,这也有助于避免共享跨线程资源。
更多信息、示例和模式/反模式在微软的免费书籍《并行编程的模式:使用.NET框架理解和应用并行模式4》中有很好的描述
请在此处下载
http://www.microsoft.com/en-us/download/details.aspx?id=19222
https://stackoverflow.com/questions/11616833
复制相似问题