【问题标题】:Openmp not speeding up parallel loopOpenmp没有加速并行循环
【发布时间】:2012-11-13 06:56:22
【问题描述】:

我有以下令人尴尬的并行循环

//#pragma omp parallel for
for(i=0; i<tot; i++)
    pointer[i] = val;

为什么取消注释 #pragma 行会导致性能下降?当我使用 openmp 并行化这个 for 循环时,程序运行时间略有增加。既然每次访问都是独立的,那不应该大大提高程序的速度吗?

是否有可能如果这个 for 循环没有针对较大的 tot 值运行,开销会减慢速度?

【问题讨论】:

    标签: c multithreading performance parallel-processing openmp


    【解决方案1】:

    在共享内存环境中实现多线程性能通常取决于:

    1. 任务粒度
    2. 并行任务之间的负载平衡
    3. 并行任务数/使用的核心数
    4. 并行任务之间同步的数量;
    5. 算法的边界类型
    6. 机器架构

    我将简要概述上述各点。

    1. 您需要检查并行任务的粒度是否足以克服并行化的开销例如线程创建和同步)。也许循环的迭代次数和计算pointer[i] = val; 不足以证明线程创建的开销是合理的;然而,值得注意的是,过大的任务粒度也会导致问题,例如负载不平衡。

    2. 您必须测试负载平衡(每个线程的工作量)。理想情况下,每个线程应该计算相同数量的工作。在您的代码示例中,这没有问题;

    3. 你在使用超线程吗?!你使用的线程比内核多吗?!因为,如果您这样做,线程将开始“竞争”资源,这会导致性能下降;

    4. 通常,人们希望减少线程之间的同步量。因此,有时人们会使用更细粒度的同步机制甚至数据冗余(以及其他方法)来实现这一目标。您的代码没有这个问题。

    5. 在尝试并行化您的代码之前,您应该分析它是否受内存限制、CPU 限制等。如果它受内存限制,则可以先改善缓存使用率,然后再处理并行化。对于此任务,强烈建议使用分析器。

    6. 为了充分利用底层架构,多线程方法需要解决该架构的限制。例如,在SMP 架构中执行高效的多线程方法与在NUMA 架构中执行它是不同的。因为在后者中,必须考虑到记忆亲和性

    编辑:@Hristo lliev 的建议

    1. 线程亲和性:“将线程绑定到内核总体上提高了性能,在 NUMA 系统上甚至更多,因为它提高了数据局部性。”

    顺便说一句,我建议你阅读这个Intel Guide for Developing Multithreaded Applications.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-17
      • 2013-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多