如果更改 2 个部分中的线程数,OpenMP 线程的 SPID 是否应该更改?

2023-12-06

我有 2 个 OpenMP 并行区域(我在 Linux 下的 gcc 下使用 C++),具有不同数量的线程 - 假设一个区域有 4 个线程,另一个区域有 8 个线程。然后,如果我跑ps -T $(pidof name_of_process), 4 个 SPID 始终相同,但其余 4 个每次调用都会发生变化。输出示例:

The first output

  PID  SPID TTY      STAT   TIME COMMAND
 7578  7578 pts/1    Rl+    1:18 ./rampack casino -i banana_cube.ini --start-from=0p5 --continue=100000
 7578  7579 pts/1    Rl+    0:57 ./rampack casino -i banana_cube.ini --start-from=0p5 --continue=100000
 7578  7580 pts/1    Rl+    0:57 ./rampack casino -i banana_cube.ini --start-from=0p5 --continue=100000
 7578  7581 pts/1    Rl+    0:57 ./rampack casino -i banana_cube.ini --start-from=0p5 --continue=100000
 7578 19381 pts/1    Rl+    0:00 ./rampack casino -i banana_cube.ini --start-from=0p5 --continue=100000
 7578 19382 pts/1    Rl+    0:00 ./rampack casino -i banana_cube.ini --start-from=0p5 --continue=100000
 7578 19383 pts/1    Rl+    0:00 ./rampack casino -i banana_cube.ini --start-from=0p5 --continue=100000
 7578 19384 pts/1    Rl+    0:00 ./rampack casino -i banana_cube.ini --start-from=0p5 --continue=100000

The second output

  PID  SPID TTY      STAT   TIME COMMAND
 7578  7578 pts/1    Rl+    1:23 ./rampack casino -i banana_cube.ini --start-from=0p5 --continue=100000
 7578  7579 pts/1    Rl+    1:01 ./rampack casino -i banana_cube.ini --start-from=0p5 --continue=100000
 7578  7580 pts/1    Rl+    1:01 ./rampack casino -i banana_cube.ini --start-from=0p5 --continue=100000
 7578  7581 pts/1    Rl+    1:01 ./rampack casino -i banana_cube.ini --start-from=0p5 --continue=100000
 7578 22314 pts/1    Rl+    0:00 ./rampack casino -i banana_cube.ini --start-from=0p5 --continue=100000
 7578 22315 pts/1    Rl+    0:00 ./rampack casino -i banana_cube.ini --start-from=0p5 --continue=100000
 7578 22316 pts/1    Rl+    0:00 ./rampack casino -i banana_cube.ini --start-from=0p5 --continue=100000
 7578 22317 pts/1    Sl+    0:00 ./rampack casino -i banana_cube.ini --start-from=0p5 --continue=100000

这是否意味着 OpenMP 在进入 8 线程部分时不断创建新的 4 个线程并随后销毁(或在进入 4 线程部分时)?我想是这样,但是很多地方,例如here建议线程应该坚持并等待轮到它们。我不会关心 OpenMP 的内部工作原理,但是我有个问题内存神秘地泄漏,我开始怀疑某些线程资源没有释放(或者内存变得越来越碎片?)。

那么这是正确的行为吗?我正在使用海湾合作委员会,gcc --version: gcc-8 (Ubuntu 8.4.0-1ubuntu1~18.04) 8.4.0.

此外,如果是这种情况,是否可以强制 OpenMP 不要不断销毁并生成新线程,而不使 2 个部分使用相同数量的线程?


这可能是新线程是的。这完全取决于平台和 OpenMP 实现。此外,OpenMP 规范未指定这一点,因此是合规行为。然而,GCC 运行时 (GOMP) 和 Intel/Clang one (IOMP) 在实践中倾向于尽可能地重用线程。在我的机器(6 核)上,我无法使用 GCC-10.2 的 GOMP 和 Clang-11.0 的 IOMP 重现您的问题。此外,以下程序显示相同的线程 ID,这可能意味着它们被重用:

#include <cstdio>
#include <unistd.h>
#include <sys/types.h>

int main() {
    #pragma omp parallel num_threads(4)
    printf("%d\n", gettid());

    printf("----------\n");

    #pragma omp parallel num_threads(8)
    printf("%d\n", gettid());

    printf("----------\n");

    #pragma omp parallel num_threads(4)
    printf("%d\n", gettid());

/*
    // Update n°1
    printf("----------\n");

    #pragma omp parallel num_threads(8)
    printf("%d\n", gettid());
*/
}

您应该检查该程序的结果。如果您无法在这个简单的示例中重现程序的行为,则意味着该问题特定于您的应用程序的行为。这可能表明您使用了多个相互冲突的 OpenMP 运行时。要检查这个假设,请设置环境变量OMP_DISPLAY_ENV=TRUE并查看结果。当您使用嵌套区域时,这种行为也经常出现。


更新n°1:对于另一部分 8 个线程,GCC-10.2 上的 GOMP 创建新的不需要的线程,而 Clang-11.0 上的 IOMP 不会创建额外的线程。这可能是一个错误(或者是 GOMP 的一个非常令人惊讶的行为)。

更新n°2:虽然运行时的行为是实现定义的,但您可以使用环境变量向运行时提供一些提示OMP_DYNAMIC。以下是 OpenMP 规范的规定:

The OMP_DYNAMIC环境变量控制用于执行的线程数量的动态调整parallel区域通过设置的初始值dyn-var智能网联汽车。该环境变量的值必须是以下之一:true | false。如果环境变量设置为true, OpenMP 实现可能会调整用于执行的线程数parallel区域以优化系统资源的使用。如果环境变量设置为false,线程数的动态调整被禁用。程序的行为是实现定义的,如果OMP_DYNAMIC两者都不是true nor false.

然而,使用OMP_DYNAMIC=TRUE不能解决 GOMP/GCC 上的问题。此外,在 GOMP/GCC 和 IOMP/Clang 上,它将创建的线程数量限制为可用硬件线程的数量(至少在我的机器上)。


请记住,观察到的 OpenMP 运行时行为符合规范,您的程序不应假设没有创建新线程(尽管您可能希望为了性能而调整行为)。

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

如果更改 2 个部分中的线程数,OpenMP 线程的 SPID 是否应该更改? 的相关文章

  • 单元测试验证失败

    我正在运行我的单元测试PostMyModel路线 然而 在PostMyModel 我用的是线Validate
  • 如何在另一个应用程序中挂钩 api 调用

    我正在尝试挂钩另一个应用程序的 ExtTextOut 和 DrawTextExt GDI 方法调用 我知道我需要使用 GetProcAddress 来查找 gdi32 dll 中那些方法的地址 并用我的函数的地址覆盖我想要挂钩的进程中的地址
  • 在 OnModelCreating 期间设置列名称

    Issue 我目前正在尝试通过设置的属性为我的表及其列添加前缀 我正在使用实体框架核心 我已经正确地为表名添加了前缀 但我似乎无法弄清楚列的前缀 我有一种感觉 我需要使用反射 我已经留下了我的 可能很糟糕的 反思尝试 有人有办法在实体中设置
  • 将完整模板参数值映射到原始类型

    我想将数字映射到类型 在这个例子中 我将创建一个函数 将 sizeof 结果映射到有符号的原始类型 我想知道是否有更好的方法来完成我在现代 C 中所做的事情 即采用模板化值并将其转换为类型 现在 这可以将大小转换为已知类型 但我似乎无法在标
  • 解析 JWT 令牌以仅获取有效负载内容,无需 C# 或 Blazor 中的外部库

    我正在使用 Blazor 编写可以访问 JWT 的客户端应用程序 我想知道一种简单的方法来读取令牌有效负载内容而不添加额外的依赖项 因为我不需要其他信息 也不需要验证令牌 我认为解析有效负载内容应该足够简单 只需将其写入方法即可 JwtTo
  • 在 C# 中调用 C++ 库 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我有很多用 C 编写的库 我想从 C 调用这些库 但是 我遇到了很多问题 我想知道是否有书籍或指南告诉我如何做到这一点 Dll导入 htt
  • 检测到堆栈崩溃

    我正在执行我的 a out 文件 执行后 程序运行一段时间 然后退出并显示消息 stack smashing detected a out terminated Backtrace lib tls i686 cmov libc so 6 f
  • 如何制作可启动程序?

    所以 这个问题可能看起来很奇怪 但假设我编译了 int main void int x 3 int y 4 int z x y 是否可以让CPU这样运行 如何 例如 这允许我写入监视器吗 如果我没记错的话 内存中有些地方可以写入要显示的内容
  • 为什么'enable_if'不能用于禁用这里声明

    include
  • 将表(行)与 OpenXML SDK 2.5 保持在一起

    我想在 Word 文档中生成多个表 每行 2 行 但我想将这两行保留在一起 如果可能的话 new KeepNext 第一行不起作用 new KeepNext 第一行的最后一段不起作用 new CantSplit 放在桌子上不起作用 在所有情
  • 将接口转换为其具体实现对象,反之亦然?

    在 C 中 当我有一个接口和几个具体实现时 我可以将接口强制转换为具体类型 还是将具体类型强制转换为接口 这种情况下的规则是什么 Java 和 C 中都允许这两个方向 向下转型需要显式转型 如果对象类型不正确 可能会抛出异常 然而 向上转换
  • 从BackgroundWorker线程更新图像UI属性

    在我正在编写的 WPF 应用程序中 我有一个 TransformedBitmap 属性 该属性绑定到 UI 上的 Image 对象 每当我更改此属性时 图像就会更新 因此显示在屏幕上的图像也会更新 为了防止在检索下一张图像时 UI 冻结或变
  • 如何从 Rx Subscribe 回调异步函数?

    我想回调 Rx 订阅中的异步函数 例如 像那样 public class Consumer private readonly Service service new Service public ReplaySubject
  • 从浏览器访问本地文件?

    您好 我想从浏览器访问系统的本地文件 由于涉及大量安全检查 是否可以通过某种方式实现这一目标 或使用 ActiveX 或 Java Applet 的任何其他工作环境 请帮帮我 要通过浏览器访问本地文件 您可以使用签名的 Java Apple
  • 如何调试 .NET 运行时中的内部错误?

    我正在尝试调试一些处理大文件的工作 代码本身works 但 NET 运行时本身会报告零星错误 对于上下文 这里的处理是一个 1 5GB 文件 仅加载到内存中一次 在循环中处理和释放 故意尝试重现此否则不可预测的错误 我的测试片段基本上是 t
  • 需要提取字符串中点后的最后一个数字,如“7.8.9.1.5.1.100”

    我需要提取 C 字符串中最后一个点后面的最后一个数字 例如 7 8 9 1 5 1 100 并将其存储在整数中 Added 该字符串也可以是 7 8 9 1 5 1 1 或 7 8 9 1 5 1 0 我还想验证它在最后一个点之前恰好是 7
  • PyQt 中的线程和信号问题

    我在 PyQt 中的线程之间进行通信时遇到一些问题 我使用信号在两个线程 发送者和监听者 之间进行通信 发送者发送消息 期望被监听者接收 但是 没有收到任何消息 谁能建议可能出了什么问题 我确信这一定很简单 但我已经环顾了几个小时但没有发现
  • LINQ 中的“from..where”或“FirstOrDefault”

    传统上 当我尝试从数据库中获取用户的数据时 我使用了以下方法 在某种程度上 DbUsers curUser context DbUsers FirstOrDefault x gt x u LoginName id string name c
  • 结构化绑定的用例有哪些?

    C 17 标准引入了新的结构化绑定 http en cppreference com w cpp language structured binding功能 最初是proposed http www open std org jtc1 sc
  • 使用未分配的局部变量

    我遇到了一个错误 尽管声明了变量 failturetext 和 userName 错误仍然出现 谁能帮帮我吗 Use of Unassigned local variable FailureText Use of Unassigned lo

随机推荐

  • 如何为 Rails 控制台安装“readline”

    好吧 我正在尝试运行 rails console 命令 但这就是我得到的 home user rvm rubies ruby 1 8 7 p352 lib ruby 1 8 irb completion rb 10 in require n
  • SoundCloud Widget 外部控制 iOS 问题

    我在 iOS 上使用 html5 小部件的外部控件发现了一个错误 我已经用 iphone 和 ipad 进行了测试 小部件内的控件工作正常 但是在我的客户网站上http www bushytunes net和 widget api 游乐场h
  • 如何在关闭阶段之前从阶段返回值?

    我有一个 主阶段 按下按钮打开 第二阶段 其中有一个表格 用户选择表格中的一项 然后单击 asignar 按钮 这只是一个确认按钮 一旦点击 它必须将表中所选项目的代码返回到主阶段并关闭第二阶段 这是重要的代码 我有一个 INT 变量 它必
  • SQL 动态 ASC 和 DESC

    我有以下 SQL 语句 其中 order by 子句是动态传递的 如何将 order by asc and desc 动态传递给 SQL SELECT table1 prod id table2 prod name from table1
  • 将数学表达式拆分为运算符并将运算符包含在输出数组中

    我正在尝试拆分数学运算符上的数学字符串 例如 expression 7 6 3 2 5 6 7 2 5 我需要将其标记化以生成 expressionArray 7 6 3 2 5 6 我尝试在这里找到解决方案 这就是我得到的 express
  • 在 Firebase 中维护唯一用户名和额外配置文件数据的正确方法

    我正在尝试为唯一的用户名和额外的配置文件数据 例如头像等 创建一个单独的数据存储 我有以下架构 mydatabase users
  • 从非安全页面向安全 URL 提交表单

    假设我在这个位置的页面上有一个表单 http mydomain com myform htm 表格看起来像这样
  • 如何在客户端(JS 或 JQuery)将 JSON 转换为 XML [重复]

    这个问题在这里已经有答案了 是否有可能在客户端 Javascript 或 Jquery 将 JSON 数据更改为 XML 尝试使用 JQueryhttp api jquery com jQuery parseXML 您可以创建一个空的 xm
  • GridView getChildAt() 返回 null

    我正在尝试从 GridView 获取视图 不幸的是 它返回了null onCreate GridView gridview GridView findViewById R id gridView gridview getChildAt 3
  • 使用 PHP 可以实现异步 HTTP 请求吗?

    我有一个 PHP 脚本 需要从远程服务器下载多个文件 目前 我只是使用 cURL 进行循环下载和处理文件 这意味着在前一个文件完成之前它不会开始下载一个文件 这会显着增加脚本运行时间 例如 是否可以启动多个 cURL 实例 同时异步下载这些
  • 在Java中绘制Hello World最快的方法是什么

    什么是fastest使用 Java 中的 GUI 在屏幕上绘制 Hello World 的方法 1 使用最少的类数 2 执行最少的字节代码 3 JVM 调整 因此 当我在 Windows 中双击 Jar 文件时 Hello World 立即
  • 使用 IN 子句的顺序选择记录

    I have SELECT FROM Table1 WHERE Col1 IN 4 2 6 我想选择并返回具有 IN 子句中指定的指定顺序的记录 首先显示Col1 4 Col1 2 的记录 我可以用 SELECT FROM Table1 W
  • 如何将嵌套类型与 NEST 客户端一起用于 Elastic Search

    我在尝试在 Elastic Search 中的文档上使用统计方面时遇到了一些问题 这导致 Elastic Search google 群组上出现以下帖子 请参阅https groups google com forum topic elas
  • 导入键盘出现 python 错误

    所以我使用下载了 python 2 7 的键盘模块 pip install keyboard 安装后我尝试将其导入 import keyboard as keyboard 但是它给了我这个错误 File C Python27 lib sit
  • 静默使用 Microsoft XPS Document Writer 打印机创建 XPS

    几天来 我一直在努力在没有对话框的情况下将 XPS 打印到文件 我读过 CodeGuru 和 Feng Yuan MSDN 中有关此事的帖子 以及这里的许多讨论主题 但我仍然迷失 具体来说 我的场景是我必须使用一个第三方 API 它会打印到
  • 递归地伊托亚

    我一直在尝试写一个递归的函数版本itoa 代码如下所示 void itoa int n char s static int i 0 if n 10 0 itoa n 10 s else if n lt 0 i 1 s 0 is allrea
  • Gimp 程序中的 OpenCV Python 脚本 - 草地/硬表面边缘检测

    我想开发一个 Python OpenCV 脚本来复制 改进我开发的 Gimp 程序 该过程的目标是提供一个遵循草地和硬表面之间分界线的 x y 点阵列 这个阵列将使我能够完成我的 500 磅 54 英寸宽的压力清洗机器人 它有一个 Rasp
  • 超高性能 C/C++ 哈希映射(表、字典)[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我需要将原始键 int 可能是long 映射到高性能哈希映射数据结构中的结构值 我的程序将有几百个这样的地图 每个地图通常最多有几千个条目 然而 地
  • 检票处的脚手架

    是否有适用于 Wicket 1 5 的有效 支持和维护的脚手架解决方案 我知道 Wicketopia 位于两个不同地点来源锻造 and github但这仍然针对 wicket 1 4 带来了自己的 wicket 并且发送到邮件列表的邮件在几
  • 如果更改 2 个部分中的线程数,OpenMP 线程的 SPID 是否应该更改?

    我有 2 个 OpenMP 并行区域 我在 Linux 下的 gcc 下使用 C 具有不同数量的线程 假设一个区域有 4 个线程 另一个区域有 8 个线程 然后 如果我跑ps T pidof name of process 4 个 SPID