在 openmp 中,omp_get_thread_num是否绑定到物理线程?

In openmp is omp_get_thread_num tied to the physical thread?

本文关键字:绑定 线程 是否 thread openmp omp get num      更新时间:2023-10-16

我知道 OpenMP 使用线程池来重用物理线程。我的问题是,从omp_get_thread_num获得的线程编号是否与物理线程相关联?

换句话说,在所有并行区域中,omp_get_thread_numgettid(gettid 手册页(的映射是否始终相同?


OpenMP 规范中的第 3.2.4 节(链接(

捆绑

为omp_get_thread_num区域设置的绑定线程是当前的 团队。omp_get_thread_num区域的绑定区域是 最里面的封闭平行区域。

影响

omp_get_thread_num例程返回 调用线程,在执行并行区域的 10 个组中 常规区域绑定。线程编号为整数 介于 0 和 1 之间,小于 omp_get_num_threads 返回的值 包容。团队主线程的线程数为 0。 如果从 程序。


使用 gettid 系统调用进行简单测试

下面使用 GCC 的 CentOS 7 代码,为我提供了两个并行区域相同的映射。但我不确定这是否只是一个特例。

#include <unistd.h>
#include <sys/syscall.h>
#include <iostream>
#include <omp.h>
int main(int argc, char *argv[]) {
std::cout << "Entering region 1:" << std::endl;
#pragma omp parallel
{
#pragma omp critical
std::cout << "num: "<< omp_get_thread_num() << " => tid: " << syscall(__NR_gettid) << std::endl;
}
std::cout << "------------------------------------------------------------" << std::endl;
std::cout << "Entering region 2:" << std::endl;

#pragma omp parallel
{
#pragma omp critical
std::cout << "num: "<< omp_get_thread_num() << " => tid: " << syscall(__NR_gettid) << std::endl;
}

return 0;
}

这是我在 CentOS 7 中使用 GCC (5.2( 获得的输出。

Entering region 1:
num: 0 => tid: 625
num: 5 => tid: 630
num: 7 => tid: 632
num: 11 => tid: 636
num: 3 => tid: 628
num: 13 => tid: 638
num: 1 => tid: 626
num: 9 => tid: 634
num: 6 => tid: 631
num: 10 => tid: 635
num: 12 => tid: 637
num: 2 => tid: 627
num: 4 => tid: 629
num: 8 => tid: 633
num: 14 => tid: 639
num: 15 => tid: 640
------------------------------------------------------------
Entering region 2:
num: 4 => tid: 629
num: 12 => tid: 637
num: 15 => tid: 640
num: 5 => tid: 630
num: 8 => tid: 633
num: 13 => tid: 638
num: 0 => tid: 625
num: 9 => tid: 634
num: 1 => tid: 626
num: 6 => tid: 631
num: 3 => tid: 628
num: 7 => tid: 632
num: 10 => tid: 635
num: 11 => tid: 636
num: 2 => tid: 627
num: 14 => tid: 639

编译:g++ toy.cpp -fopenmp

跨多个并行区域,无法保证。下面是一个稍作修改的示例:

int main(int argc, char *argv[]) {
std::cout << "Entering region 1:" << std::endl;
#pragma omp parallel
{
#pragma omp critical
std::cout << "num: "<< omp_get_thread_num() << " => tid: " << syscall(__NR_gettid) << std::endl;
}
std::cout << "------------------------------------------------------------" << std::endl;
std::cout << "Entering region 2:" << std::endl;
// shrinks the threadpool for libgomp
#pragma omp parallel num_threads(2)
{
#pragma omp critical
std::cout << "num: "<< omp_get_thread_num() << " => tid: " << syscall(__NR_gettid) << std::endl;
}
std::cout << "------------------------------------------------------------" << std::endl;
std::cout << "Entering region 3:" << std::endl;
#pragma omp parallel
{
#pragma omp critical
std::cout << "num: "<< omp_get_thread_num() << " => tid: " << syscall(__NR_gettid) << std::endl;
}
return 0;
}

这是输出(gcc 8.2.1(:

Entering region 1:
num: 0 => tid: 11845
num: 6 => tid: 11851
num: 3 => tid: 11848
num: 5 => tid: 11850
num: 7 => tid: 11852
num: 4 => tid: 11849
num: 2 => tid: 11847
num: 1 => tid: 11846
------------------------------------------------------------
Entering region 2:
num: 1 => tid: 11846
num: 0 => tid: 11845
------------------------------------------------------------
Entering region 3:
num: 2 => tid: 11853
num: 7 => tid: 11858
num: 5 => tid: 11856
num: 4 => tid: 11855
num: 1 => tid: 11846
num: 3 => tid: 11854
num: 0 => tid: 11845
num: 6 => tid: 11857

OpenMP 标准未指定跨并行区域的线程池。