Parallel-For 循环给出与单个 for 循环不同的求和结果。我错过了什么?
Parallel-For loop giving different sum results than single for loop. What am I missing?
我们的一个程序中有一个不明显的错误。我已经将它的至少一部分缩小到这个并行 for 循环。
i 是一个 int[],出于测试目的,填充了 0 - 99999 的整数。
runningTotal 很长。
lockObject 是一个新的 Object();
Parallel-For 循环似乎总是 return 完成时总计 704,982,704;单线程循环 returns 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];
}
根本原因是局部状态声明为int
,有时会溢出
这会间歇性地发生,并且与 Parallel.For
处理手头任务的工作线程数有关。如果将 MaxDegreeOfParallelism
限制为 1,则可以可靠地发生溢出。
修复方法是将本地状态声明为 long
:
Parallel.For(0, i.Length, () => 0L, ...)
... 那么溢出永远不会发生。除此之外,你的逻辑没有任何问题。
我们的一个程序中有一个不明显的错误。我已经将它的至少一部分缩小到这个并行 for 循环。
i 是一个 int[],出于测试目的,填充了 0 - 99999 的整数。 runningTotal 很长。 lockObject 是一个新的 Object();
Parallel-For 循环似乎总是 return 完成时总计 704,982,704;单线程循环 returns 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];
}
根本原因是局部状态声明为int
,有时会溢出
这会间歇性地发生,并且与 Parallel.For
处理手头任务的工作线程数有关。如果将 MaxDegreeOfParallelism
限制为 1,则可以可靠地发生溢出。
修复方法是将本地状态声明为 long
:
Parallel.For(0, i.Length, () => 0L, ...)
... 那么溢出永远不会发生。除此之外,你的逻辑没有任何问题。