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

时间:2018-10-20 16:36:47

标签: c++ openmp

我了解OpenMP使用线程池来重用物理线程。我的问题是从omp_get_thread_num获得的线程号是否绑定到物理线程?

换句话说,在所有并行区域中,从omp_get_thread_numgettidgettid 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​​}}

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标准未指定跨并行区域的线程池。