如何在工作线程中重用主线程创建的OMP线程池?

2024-02-24

在我的 C++ 应用程序开始附近,我的主线程使用 OMP 并行化多个 for 循环。在第一个并行化 for 循环之后,我发现所使用的线程在应用程序的持续时间内仍然存在,并且可以使用以下命令(在 CentOS 7 中工作)重用于从主线程执行的后续 OMP for 循环:

for i in $(pgrep myApplication); do ps -mo pid,tid,fname,user,psr -p $i;done

后来在我的程序中,我从主线程启动了一个 boost 线程,其中我使用 OMP 并行化了一个 for 循环。此时,我看到创建了一组全新的线程,这具有相当大的开销。

是否可以使boost线程内的OMP并行for循环重用主线程创建的原始OMP线程池?

编辑:一些伪代码:

myFun(data)
{

    // Want to reuse OMP thread pool from main here.
    omp parallel for
    for(int i = 0; i < N; ++i)
    {
       // Work on data
    }

}


main
{

    // Thread pool created here.
    omp parallel for
    for(int i = 0; i < N; ++i)
    {
        // do stuff
    }


    boost::thread myThread(myFun) // Constructor starts thread.

    // Do some serial stuff, no OMP.

    myThread.join();


}

OpenMP 与其他线程机制的交互被故意排除在规范之外,因此在很大程度上依赖于实现。 GNU OpenMP 运行时在 TLS 中保留指向线程池的指针,并将其传播到(嵌套)团队。线程开始于pthread_create (or boost::thread or std::thread)不继承指针,因此产生一个新的池。其他 OpenMP 运行时也可能出现这种情况。

标准中有一个要求,基本上强制在大多数实现中执行这种行为。这是关于语义的线程私有变量以及如何在从同一线程分叉的不同并行区域中保留它们的值(OpenMP 标准,2.15.2 threadprivate指示 http://www.openmp.org/mp-documents/openmp-4.5.pdf#subsection.2.15.2):

非初始线程的 threadprivate 变量中的数据值保证在两个连续的活动之间持续存在parallel仅当满足以下所有条件时才区域:

  • Neither parallel区域嵌套在另一个显式并行区域内。
  • 用于执行两者的线程数parallel地区是一样的。
  • 用于执行两者的线程亲和性策略parallel地区是一样的。
  • 的价值dyn-var封闭任务区域中的内部控制变量是false在进入两者时parallel地区。

如果这些条件全部成立,并且在两个区域中都引用了 threadprivate 变量,则在各自区域中具有相同线程号的线程将引用该变量的相同副本。

除了性能之外,这可能是在 OpenMP 运行时中使用线程池的主要原因。

现在,假设由两个单独的线程分叉的两个并行区域共享同一个工作线程池。第一个线程分叉了一个并行区域,并设置了一些线程私有变量。随后,同一个线程会分叉出第二个并行区域,并在其中使用这些 threadprivate 变量。但在两个并行区域之间的某个地方,第二个线程分叉出一个并行区域,并使用同一池中的工作线程。由于大多数实现在 TLS 中保留线程私有变量,因此无法再断言上述语义。一种可能的解决方案是为每个单独的线程向池中添加新的工作线程,这与创建新的线程池没有太大区别。

我不知道有任何解决方法可以使工作线程池共享。如果可能的话,它也不会是可移植的,因此 OpenMP 的主要优势将会丧失。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在工作线程中重用主线程创建的OMP线程池? 的相关文章

  • 为什么 C# Array.BinarySearch 这么快?

    我已经实施了一个很简单用于在整数数组中查找整数的 C 中的 binarySearch 实现 二分查找 static int binarySearch int arr int i int low 0 high arr Length 1 mid
  • 临时表是线程安全的吗?

    我正在使用 SQL Server 2000 它的许多存储过程广泛使用临时表 数据库的流量很大 我担心创建和删除临时表的线程安全性 假设我有一个存储过程 它创建了一些临时表 它甚至可以将临时表连接到其他临时表等 并且还可以说两个用户同时执行存
  • 不支持将数据直接绑定到存储查询(DbSet、DbQuery、DbSqlQuery)

    正在编码视觉工作室2012并使用实体模型作为我的数据层 但是 当页面尝试加载时 上面提到的标题 我使用 Linq 语句的下拉控件往往会引发未处理的异常 下面是我的代码 using AdventureWorksEntities dw new
  • C# 中通过 Process.Kill() 终止的进程的退出代码

    如果在我的 C 应用程序中 我正在创建一个可以正常终止或开始行为异常的子进程 在这种情况下 我通过调用 Process Kill 来终止它 但是 我想知道该进程是否已退出通常情况下 我知道我可以获得终止进程的错误代码 但是正常的退出代码是什
  • C#中如何移动PictureBox?

    我已经使用此代码来移动图片框pictureBox MouseMove event pictureBox Location new System Drawing Point e Location 但是当我尝试执行时 图片框闪烁并且无法识别确切
  • C++ OpenSSL 导出私钥

    到目前为止 我成功地使用了 SSL 但遇到了令人困惑的障碍 我生成了 RSA 密钥对 之前使用 PEM write bio RSAPrivateKey 来导出它们 然而 手册页声称该格式已经过时 实际上它看起来与通常的 PEM 格式不同 相
  • 转发声明和包含

    在使用库时 无论是我自己的还是外部的 都有很多带有前向声明的类 根据情况 相同的类也包含在内 当我使用某个类时 我需要知道该类使用的某些对象是前向声明的还是 include d 原因是我想知道是否应该包含两个标题还是只包含一个标题 现在我知
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 这些作业之间是否存在顺序点?

    以下代码中的两个赋值之间是否存在序列点 f f x 1 1 x 2 不 没有 在这种情况下 标准确实是含糊不清的 如果你想确认这一点 gcc 有这个非常酷的选项 Wsequence point在这种情况下 它会警告您该操作可能未定义
  • 链接器错误:已定义

    我尝试在 Microsoft Visual Studio 2012 中编译我的 Visual C 项目 使用 MFC 但出现以下错误 error LNK2005 void cdecl operator new unsigned int 2
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • 为什么编译时浮点计算可能不会得到与运行时计算相同的结果?

    In the speaker mentioned Compile time floating point calculations might not have the same results as runtime calculation
  • 静态变量的线程安全

    class ABC implements Runnable private static int a private static int b public void run 我有一个如上所述的 Java 类 我有这个类的多个线程 在里面r
  • 如何在Xamarin中删除ViewTreeObserver?

    假设我需要获取并设置视图的高度 在 Android 中 众所周知 只有在绘制视图之后才能获取视图高度 如果您使用 Java 有很多答案 最著名的方法之一如下 取自这个答案 https stackoverflow com a 24035591
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • 哪种 C 数据类型可以表示 40 位二进制数?

    我需要表示一个40位的二进制数 应该使用哪种 C 数据类型来处理这个问题 如果您使用的是 C99 或 C11 兼容编译器 则使用int least64 t以获得最大的兼容性 或者 如果您想要无符号类型 uint least64 t 这些都定
  • 如何将服务器服务连接到 Dynamics Online

    我正在修改内部管理应用程序以连接到我们的在线托管 Dynamics 2016 实例 根据一些在线教程 我一直在使用OrganizationServiceProxy out of Microsoft Xrm Sdk Client来自 SDK
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现
  • 对来自流读取器的过滤数据执行小计

    编辑问题未得到解答 我有一个基于 1 个标准的过滤输出 前 3 个数字是 110 210 或 310 给出 3 个不同的组 从流阅读器控制台 问题已编辑 因为第一个答案是我给出的具体示例的字面解决方案 我使用的实际字符串长度为 450 个

随机推荐