In openmp is omp_get_thread_num tied to the physical thread?

Viewed 1072

I understand that OpenMP uses a thread pool to reuse the physical threads. My question is whether the thread number obtained from omp_get_thread_num is tied to the physical thread?

In other words, is the mapping omp_get_thread_num to gettid (gettid man page) always the same in all parallel regions?


Section 3.2.4 from the OpenMP specification (link)

Binding

The binding thread set for an omp_get_thread_num region is the current team. The binding region for an omp_get_thread_num region is the innermost enclosing parallel region.

Effect

The omp_get_thread_num routine returns the thread number of the calling thread, within the 10 team executing the parallel region to which the routine region binds. The thread number is an integer between 0 and one less than the value returned by omp_get_num_threads , inclusive. The thread number of the master thread of the team is 0. The routine returns 0 if it is called from the sequential part of a program.


Simple test using gettid system call

The code below CentOS 7 using GCC, gives me the same mapping for the two parallel for regions. But I am not sure if this is just a particular case.

#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;
}

Here is the output I get in CentOS 7, using 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

Compilation: g++ toy.cpp -fopenmp

1 Answers

Across multiple parallel regions it is not guaranteed. Here is a slightly modified example:

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;
}

This is the output (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

Thread pooling across parallel regions is not specified by the OpenMP standard.

Related