繁体   English   中英

为什么我的代码无法通过多线程Parallel.For循环加速?

[英]Why my code does not speed up with a multithreaded Parallel.For loop?

我尝试使用System.Threading.Tasks库将简单的顺序循环转换为并行计算循环。 代码会编译,返回正确的结果,但是它不会节省任何计算成本,否则会花费更长的时间。


编辑:抱歉,我可能已经简化了这个问题,并且在这样做时犯了一些错误。 为了附加更多信息,我在i7-4700QM上运行代码,并且在Grasshopper脚本中对其进行了引用。 这是实际的代码。 我也切换到非线程局部变量

public static class LineNet
{        
    public static List<Ray> SolveCpu(List<Speaker> sources, List<Receiver> targets, List<Panel> surfaces)
    {
        ConcurrentBag<Ray> rays = new ConcurrentBag<Ray>();
        for (int i = 0; i < sources.Count; i++)
        {
            Parallel.For(
                0,
                targets.Count,
                j =>
                {
                    Line path = new Line(sources[i].Position, targets[j].Position);
                    Ray ray = new Ray(path, i, j);
                    if (Utils.CheckObstacles(ray,surfaces))
                    {
                        rays.Add(ray);
                    }

                }
                );
        }
    }
}

Grasshopper实现只收集sources targetssurfaces ,调用Solve方法并返回rays 我知道将工作负载分配给线程很昂贵,但是它是如此昂贵吗? 还是ConcurrentBag仅阻止并行计算?

另外,我的类是不可变的(?),但是如果我使用通用的List则内核会中止该操作并引发异常,有人可以说出原因吗?

如果没有可靠,可靠地重现此问题的最佳,完整和可验证的代码示例 ,就不可能提供确定的答案。 您发布的代码甚至似乎都不是真实代码的摘录,因为声明为该方法的返回类型的类型与return语句实际返回的值不同。

但是,当然,您发布的代码似乎不太适合使用Parallel.For() 您的Line构造函数要证明并行化创建项的任务是相当昂贵的。 需要明确的是,这是唯一可能的胜利。

最后,您仍然需要将创建的所有Line实例聚合到一个列表中,因此为Parallel.For()任务创建的所有这些中间列表仅是纯开销。 而且聚合必须是序列化的(即,一次只能有一个线程可以将一个项目添加到result集合中),并且以最坏的方式(每个线程只能在放弃锁之前添加一个项目,而另一个线程却只能添加一个项目)有机会)。

坦白地说,最好将每个本地List<T>存储在一个集合中,然后在Parallel.For()返回之后一次将它们全部聚集在主线程中。 那并不是使代码的性能比直接非并行实现更好。 但是至少它不太可能变得更糟。 :)

最重要的是,您似乎没有可以从并行化中受益的工作量。 否则,您需要以更清晰,更详细的方式解释该思想的基础。

如果我使用通用列表,则内核会中止操作并引发异常,有人可以说出原因吗?

您已经在使用List<T>作为它的每个任务的本地数据,并且确实可以,因为任务不共享其本地数据。

但是,如果您问为什么尝试使用List<T>而不是ConcurrentBag<T>作为result变量,为什么会得到异常,这完全是可以预期的。 List<T>类不是线程安全的,但是Parallel.For()将允许其运行的每个任务与所有其他任务同时执行localFinally委托。 因此,您有多个线程都试图同时修改同一个非线程安全的集合。 这是灾难的秘诀。 幸运的是您得到了例外。 实际的行为是不确定的,很可能您只是破坏数据结构而导致运行时异常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM