【发布时间】:2013-11-09 17:43:17
【问题描述】:
我目前有一个 for 循环来比较 2 个数组并确定它们是否相等。
public override bool Equals(object obj)
{
RushHourPathLengthNode otherNode = (RushHourPathLengthNode)obj;
// Compare their carCoords and return false as soon as we find a difference
for (int i = 0, l = carCoords.Length; i < l; ++i)
if (carCoords[i].x != otherNode.carCoords[i].x || carCoords[i].y != otherNode.carCoords[i].y)
return false;
return true;
}
这很好用,但它是我的程序中最慢的部分之一。这样我的测试用例大约需要 7 秒来计算。
虽然我可能有 50K 任务正在运行,但我的 i7 860 CPU(4 核,8 线程)上的 CPU 使用率约为 50%。
我的想法是使用并行 for 循环来最大化 CPU 使用率并使其更快。这就是我想出的。
public override bool Equals(object obj)
{
RushHourPathLengthNode otherNode = (RushHourPathLengthNode)obj;
bool result = true;
Parallel.For(0, carCoords.Length, (i, loopState) =>{
if (!result)
loopState.Stop();
if (carCoords[i].x != otherNode.carCoords[i].x || carCoords[i].y != otherNode.carCoords[i].y)
result = false;
});
return result;
}
在我看来,它会尝试并行运行,并且一旦发现差异,它就会因为 loopState.Stop 而停止工作。这样 CPU 使用率是 90%+,但我的测试用例需要大约 35 秒来计算,我不明白为什么。
我的实现有问题还是我的整个方法有问题?
编辑: carCoords.Length 将是一个介于 2 和 +-100 之间的值。听起来该值太低,无法证明并行执行此操作是合理的。
【问题讨论】:
-
好吧,您想在发现差异后立即调用 loopState.Stop(),而不是稍后。例如,在结果=假之前;陈述。我不知道您的示例有多有效,但可能是结果始终被缓存并且永远不会到达其他线程。或者如果是,那么稍后。
-
另外,carCoords.Length 通常有多大?我怀疑您不会从并行执行中获得任何好处。
-
您需要锁定结果变量
-
@SriramSakthivel 不正确。结果只设置为
false,两个线程是否同时执行都没有关系。 -
@JeffreySax 我知道,但没有锁或 volatile 其他线程可能看不到更新的值。值可能被缓存。锁确保内存屏障,因此更新的值将在所有线程中看到。如果错了,请纠正我。
标签: c# .net parallel-processing task-parallel-library