我有几个使用传统语法编写的循环
foreach(x in xs) {....}
其中一些循环在计算方面非常密集,我只是使用如下并行语法更改了它们:
Parallel.ForEach(x, xs => {...});
我看到性能大幅提升!!现在我的问题是:我是在使用并行多线程引入错误吗?我读到线程安全很复杂,并且会产生奇怪的错误;我应该担心什么?
我有几个使用传统语法编写的循环
foreach(x in xs) {....}
其中一些循环在计算方面非常密集,我只是使用如下并行语法更改了它们:
Parallel.ForEach(x, xs => {...});
我看到性能大幅提升!!现在我的问题是:我是在使用并行多线程引入错误吗?我读到线程安全很复杂,并且会产生奇怪的错误;我应该担心什么?
访问共享状态很可能不会产生预期的结果。简单的例子:
int sum = 0;
for (int i = 0; i < 1000000; i++)
{
sum++;
}
将其更改为
Parallel.For(0, 1000000, i => { sum++; });
你会看到sum
会有一些随机值,因为多个线程正在读/写sum
。
如果您锁定更新,您将解决问题,但您实际上会将操作再次转换为顺序操作。
您需要确保循环中发生的任何事情都是安全的。
Microsoft Patterns and Practices 写了一本书来解释所有这些以及更多内容。在简单地更改代码以使用并行循环之前,您应该检查一下。
可以肯定地说 - 发布您的迭代/循环代码。
但总的来说,您的迭代应该彼此独立,并尽量避免共享状态。跨并行迭代资源的任何共享资源都可能引入错误。
此外,当您的计算依赖于其他一些计算或并行操作或循环时,更好地使用 TPL 任务链,它还有助于避免共享跨线程资源。
更多信息和示例以及模式/反模式在免费的 Microsoft 书籍中得到了很好的描述:并行编程模式:使用 .NET Framework 4 理解和应用并行模式
在这里下载
http://www.microsoft.com/en-us/download/details.aspx?id=19222