【发布时间】:2016-01-13 06:33:18
【问题描述】:
我们的一个程序中有一个不为人知的错误。我已经将它的至少一部分缩小到这个并行for循环。
i 是一个 int[],用于测试目的,填充整数 0 - 99999。 runningTotal 很长。 lockObject 是一个新的 Object();
Parallel-For 循环在完成时似乎总是返回总数 704,982,704;单线程循环返回 4,999,950,000。
显然是线程问题,但我只是没有看到错误。 Parallel-For 循环是否正确实施?
相关代码如下:
//i int[] test ---------------------------------------------
object lockObject = new object();
int[] i = new int[100000];
for (int x = 0; x < i.Length; x++)
{
i[x] = x;
}
long runningTotal = 0;
Parallel.For(0, i.Length,
() => 0,
(x, loopState, subtotal) =>
{
subtotal += i[x];
return subtotal;
},
(s) =>
{
lock (lockObject)
{
runningTotal += s;
}
}
);
runningTotal = 0;
for (int x = 0; x < i.Length; x++)
{
runningTotal += i[x];
}
【问题讨论】:
-
这真的很奇特。当
localinit返回 0 (Int32) 时,它会在我的测试中间歇性溢出,但如果localinit是Int64(Parallel.For(0, i.Length, () => 0L ...),则可以可靠地工作 -
我尝试了您的建议,是的,它现在运行良好,似乎已经解决了我们的问题。谢谢!如果您可以将其放入“响应”中,我会将其标记为答案。
-
在我确切地知道问题发生的原因之前,这并不是我可以满意的答案。得到全面的解释后,我会进行一些挖掘并报告。
-
我想我知道它是什么。并行worker数
-
也许 init 必须被标记为 long,因为即使它在并行循环中,也可能只分配了 1 个任务,因此会导致事情溢出。并行度由系统的底层组件自动管理。这就是你的倾向吗?
标签: multithreading c#-4.0 task-parallel-library parallel-for