1

With the abundance of techniques being employed to increase parallelization in today's compiler-tools (especially auto-parallelization of certain viable for-constructs, c.f. the Intel C++ Compiler, Microsoft Visual Studio 2011, alongside various others), I wondered if parallelization is always guaranteed to improve or have no impact on performance.

Are there any cases in which parallelization would have a distinctly negative impact on performance?

A quick internet search didn't yield much hope, so I decided to turn here to see if anyone has any knowledge of cases where parallelization has a detrimental impact on performance, or better yet, experience in a project where parallelization actually caused difficulties.

I am also curious about whether there are any negative performance implication of auto-vectorization, although I find it quite unlikely that there would be.

Thanks in advance!

4

4 回答 4

3

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

这些幻灯片的最后是一些关于自动矢量化的示例和统计数据,这些示例和统计数据会使性能变得更糟。

于 2012-06-14T13:12:34.847 回答
3

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

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

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

于 2012-06-14T13:33:15.630 回答
1

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

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

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

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

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

于 2012-06-14T11:54:56.210 回答
1

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

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

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

所以都应该合理使用。

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

数据和任务并行的潜在陷阱

并行 LINQ (PLINQ) 的潜在缺陷

描述常见问题和陷阱的好书: 并行编程模式:使用 .NET Framework 4 理解和应用并行模式

于 2012-06-14T11:34:49.337 回答