【问题标题】:Can parallelization have a negative performance impact?并行化会对性能产生负面影响吗?
【发布时间】:2012-06-14 21:33:15
【问题描述】:

随着当今编译器工具(尤其是某些可行的for-constructs、c.f. 英特尔 C++ 编译器、Microsoft Visual Studio 2011 以及其他各种工具的自动并行化)中的大量技术被用于增加并行化,我想知道如果始终保证并行化可以提高性能或对性能没有影响。

是否存在并行化会对性能产生明显负面影响的情况?

快速的互联网搜索并没有产生太大的希望,所以我决定转向这里,看看是否有人知道并行化会对性能产生不利影响的情况,或者更好的是,有在并行化实际导致的项目中的经验困难。

我也很好奇自动矢量化是否会对性能产生负面影响,尽管我觉得不太可能。

提前致谢!

【问题讨论】:

    标签: performance optimization parallel-processing vectorization


    【解决方案1】:

    并行化通常涉及不同处理元素之间的一些抽象数据交换,因为并非所有处理元素都可以独占访问完成其计算部分所需的所有数据。它可以是 MPI 作业中不同进程之间传递的消息,也可以是多线程程序中的同步操作。传递数据或同步事物需要时间,这就是为什么它通常被称为通信同步开销。根据开销和计算之间的比率,存在不同类别的问题。

    根本不需要通信或同步的并行算法被称为平凡(或“尴尬”)并行问题。此类的一个示例是光线跟踪应用程序:每个像素都可以独立于所有其他像素进行计算。此类中的问题与使用的处理元素的数量成线性关系(有时甚至是由于缓存效应的超线性) - 给它两倍的处理元素,执行计算的时间将减少两倍。

    如果涉及到任何数量的通信或同步,那么随着通信/同步和计算之间的比率增加,事情会变得越来越糟。通常这是当问题大小保持固定时的情况,因为增加了处理元素的数量。通常开销会随着处理元素的数量而增加,而每个元素的计算量会减少。

    【讨论】:

      【解决方案2】:

      理论上,自动矢量化可能会陷入“陷阱”,其中将所有元素放在正确位置的开销实际上大于并行处理所节省的时间。分析一段代码将花费多少时间很困难,因此编译器很难做出正确的决定。

      these slides 的末尾是一些关于自动矢量化使性能变差的示例和统计数据。

      【讨论】:

        【解决方案3】:

        通常使用合理的并行化(平均并行处理)会产生积极的性能影响。

        但在某些情况下,从开发人员的角度来看,它可能会造成负面影响:

        1. 分配给多个线程以进行并行和/或多线程处理时。
        2. 当迭代较小时分叉/连接并行和循环并行化,分配线程比简单地同步处理项目花费更多的时间和资源
        3. 典型的多线程/并行执行问题,如死锁、活锁、线程耗尽、竞争条件等。
        4. 调试和诊断,更难发现错误

        所以都应该合理使用。

        还有一些链接。抱歉,它们是 .NET/Microsoft 特定的,但描述的问题是相同的:

        Potential Pitfalls in Data and Task Parallelism

        Potential Pitfalls with Parallel LINQ (PLINQ)

        描述常见问题和陷阱的好书: Patterns for Parallel Programming: Understanding and Applying Parallel Patterns with the .NET Framework 4

        【讨论】:

          【解决方案4】:

          从更理论的角度来看,您可能对NC 中没有的问题感兴趣,即在具有多项式处理器数量的并行计算机上可在多对数时间内确定的决策问题类别。

          在我的脑海中,我想不出任何计算问题在某种程度上是不可并行的。我多次遇到的问题是并行化程度很差

          严重并行化的程序很容易比它们的顺序版本慢。这可能是由于:

          • 由于并行度太细而导致的大量开销,例如与启动/调度操作的开销相比,每个线程执行的工作量可以忽略不计。在OpenMP 中,这可能是#pragma omp parallel for schedule(dynamic,k) 用于小块大小k 的情况。
          • 重复并发访问共享资源,例如如果所有线程都必须等待顺序访问某些资源或内存位置。在 OpenMP 中,这可能是由太多或太大的 #pragma omp critical 部分引起的。
          • 过度使用慢速atomic operations 来更新线程之间共享的变量,例如使用#pragma omp atomic,在顺序情况下,将使用更快的常规内存访问。

          总而言之,在我看来,很少有本质上的顺序问题,而是大量实施不当的并行解决方案。

          【讨论】:

          • 感谢您的理论方法,我将阅读更多关于 NC 问题的信息! +1
          猜你喜欢
          • 2017-06-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-06-11
          • 2011-03-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多