使用 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 时运行的线程数不一致的主要内容,如果未能解决你的问题,请参考以下文章