并行化会对性能产生负面影响吗?

时间:2012-06-14 11:21:09

标签: performance optimization parallel-processing vectorization

利用丰富的技术来增加当今编译器工具的并行化(特别是某些可行的for - 构造的自动并行化,参见英特尔C ++编译器,Microsoft Visual Studio 2011,以及其他各种),我想知道是否始终保证并行化能够改进或对性能没有影响。

  

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

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

我也很好奇自动矢量化是否存在任何负面的性能影响,尽管我发现它不太可能存在。

提前致谢!

4 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:3)

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

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

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

答案 2 :(得分:1)

通常使用合理的并行化(均值并行处理)可以得到正的性能。

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

  1. 分配给多个线程进行并行和/或多线程处理时。
  2. 当迭代很小时,fork / join并行性和循环并行化并且分配线程比简单同步处理项目花费更多时间和资源
  3. 典型的多线程/并行执行问题,如死锁,活锁,线程困扰,竞争条件等。
  4. 调试和诊断,更难找到错误
  5. 所以都应该合理使用。

    还有一些链接。对不起,他们是.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

答案 3 :(得分:1)

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

在我的脑海中,我无法想到任何不以某种方式可并行化的计算问题。我遇到的很多次是严重并行化的问题。

糟糕的并行化程序很容易比顺序版本慢。这可能是因为:

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

总而言之,在我看来,几乎没有固有的顺序问题,而是大量实施并行解决方案。