我了解OpenMP使用线程池来重用物理线程。我的问题是从omp_get_thread_num
获得的线程号是否绑定到物理线程?
换句话说,在所有并行区域中,从omp_get_thread_num
到gettid
(gettid man page)的映射是否总是相同?
OpenMP规范(link)第3.2.4节
绑定
为omp_get_thread_num区域设置的绑定线程是当前的 球队。 omp_get_thread_num区域的绑定区域是 最里面的平行区域。
效果
omp_get_thread_num例程返回线程的线程号。 调用线程,在执行并行区域的10个团队中 常规区域绑定的对象。线程号是整数 比omp_get_num_threads返回的值小0到1之间 , 包括的。团队主线程的线程号为0。 如果从a的顺序部分调用该例程,则返回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;
}
这是我使用GCC(5.2)在CentOS 7中获得的输出。
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
编译:{{1}}
答案 0 :(得分:2)
在多个平行区域中不能保证。这是一个稍作修改的示例:
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标准未指定跨并行区域的线程池。