c - Openmp 没有加速并行循环

标签 c multithreading performance parallel-processing openmp

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

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

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

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

最佳答案

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

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

我将简要概述上述各点。

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

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

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

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

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

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

编辑:来自@Hristo lliev 的建议

  1. 线程亲和性:“将线程绑定(bind)到核心可以提高整体性能,甚至可以提高 NUMA 系统的性能,因为它可以改善数据局部性。”

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

关于c - Openmp 没有加速并行循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13553995/

相关文章:

c# - 锁定main()线程

从 scala 调用的 Java 方法运行缓慢

Linux:大文件与大量文件

java - JMeter - 如何将多行响应数据传递给 ForEach Controller 请求

java - 从单独的线程持续更新循环内的 JLabel

c - 解密 x86 汇编函数

c++ - 在 C/C++ 中连接字符串

c - 混合使用 Objective-C 和 C 有哪些陷阱?

c - 在理解将 char* [] 传递给函数方面需要帮助

javascript - 页面在浏览器中被杀死后如何运行任务?