使用 openmp 时运行的线程数不一致

Posted

技术标签:

【中文标题】使用 openmp 时运行的线程数不一致【英文标题】:Inconsistent number of threads running when using openmp 【发布时间】:2015-02-02 06:15:50 【问题描述】:

我有一个带有openmp并行的c程序。机器有24个内核。每个并行任务访问 mmap 文件中的不同位置并进行一些计算。我没有设置任何特定数量的线程。我让openmp决定。当我查看 htop 时,我发现一次运行的线程数存在巨大的不一致。有时所有 24 个内核都 100% 使用,整个任务很快完成,但有时 htop 显示只有 2-3 个线程(与我的程序以外的所有其他进程/线程结合)正在运行。我还看到只有 2-3 个线程在运行时,大多数内核几乎都没有被占用。

在任何给定时间运行的线程数量不一致的原因可能是什么?有没有一种方法可以通过我的程序控制行为,以便结果在某种程度上是可预测的。目前我的程序可能需要 7 秒或有时超过一分钟才能完成。

提前致谢!

添加 gprof 输出

Each sample counts as 0.01 seconds.
%   cumulative   self              self     total
time   seconds   seconds    calls  ms/call  ms/call  name
43.50     26.62    26.62                             __libc_csu_init
41.91     52.26    25.65     4985     5.14     5.14  _get_entity
9.08     57.81     5.55                             __libc_csu_fini
4.61     60.64     2.82     5000     0.56     0.56  common_count_2
0.74     61.09     0.45        1   450.27   450.27  _get_first_entity
0.16     61.19     0.10                             main
0.00     61.19     0.00        1     0.00     0.00  copy_index

【问题讨论】:

您需要提供更多信息。机器是否与其他用户共享?当您说您的程序需要 7 秒到一分钟以上时,是在完全相同的条件下(例如输入)吗?构造运行的并行是什么? 是的,这台机器是共享的。两次运行的输入相同。可能还有其他我不知道的情况。用 gprof 输出更新了问题。我看到在较慢的运行中,很多时间都花在了 __libc_csu_init 中。我不知道这个功能的目的。程序有点长。我将尝试将其抽象出来并通过一些代码。 会不会是如果我使用-pg编译,我通常在开发时这样做,第一次运行可能会更慢?我注意到第一次运行速度较慢,然后是一致的。我只是将 -pg 留在那里,并不想删除它,这可能会导致一些副作用。还需要进一步分析。 你的编译选项是什么?您是否使用 -O2-O3 等优化进行编译? 我正在使用gcc -ldb -fopenmp -lcredis -ocaff_ht -DHASH_BLOOM=27 caff_ht.c 进行编译。虽然 cridis 库已链接,但代码并未使用它。现在,经过进一步分析,我也看到 -pg 选项没有任何区别。如果没有它,我会看到相同的不一致行为。 【参考方案1】:

OpenMP 试图通过减少线程数来帮助您,因为它认为您没有足够的并行度。此行为可以通过OMP_DYNAMIC 环境变量或代码中的omp_set_dynamic 函数调用来控制。默认情况下它应该被禁用,但值得仔细检查。

不应将动态一词的这种用法与指代动态调度的 schedule(dynamic) 混淆。 OMP_DYNAMIC 指的是动态数量的线程,而不是动态地将工作调度到固定数量的线程(调度(动态)。

【讨论】:

omp_set_dynamic(1) 不会改变行为。 您应该使用 omp_set_dynamic(0) 禁用它,从而保持线程数不变。

以上是关于使用 openmp 时运行的线程数不一致的主要内容,如果未能解决你的问题,请参考以下文章

openMP C++ 简单并行区域 - 输出不一致

在 OpenMP 中重置线程局部变量

OpenMP 中的同步

「日志」Navicat统计的行数竟然和表实际行数不一致

openmp/C++ 简单并行区域返回不一致的结果

使用 Armadillo 和 OpenBLAS 进行多线程处理时性能不一致