title: In openmp is omp_get_thread_num tied to the physical thread?
body: <p>I understand that OpenMP uses a thread pool to reuse the physical threads. My question is whether the thread number obtained from <code>omp_get_thread_num</code> is tied to the physical thread?  </p>
  
  <p>In other words, is the mapping <code>omp_get_thread_num</code> to <code>gettid</code> (<a href="http://man7.org/linux/man-pages/man2/gettid.2.html" rel="nofollow noreferrer">gettid man page</a>) always the same in all parallel regions?</p>
  
  <hr>
  
  <p><strong>Section 3.2.4 from the OpenMP specification (<a href="https://www.openmp.org/wp-content/uploads/openmp-4.5.pdf" rel="nofollow noreferrer">link</a>)</strong> </p>
  
  <blockquote>
    <p>Binding</p>
    
    <p>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.</p>
    
    <p>Effect</p>
    
    <p>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.</p>
  </blockquote>
  
  <hr>
  
  <p><strong>Simple test using gettid system call</strong></p>
  
  <p>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.</p>
  
  <pre><code>#include &lt;unistd.h&gt;
  #include &lt;sys/syscall.h&gt;
  #include &lt;iostream&gt;
  #include &lt;omp.h&gt;
  
  int main(int argc, char *argv[]) {
  
      std::cout &lt;&lt; "Entering region 1:" &lt;&lt; std::endl;
  
      #pragma omp parallel
      {
          #pragma omp critical
          std::cout &lt;&lt; "num: "&lt;&lt; omp_get_thread_num() &lt;&lt; " =&gt; tid: " &lt;&lt; syscall(__NR_gettid) &lt;&lt; std::endl;
      }
  
      std::cout &lt;&lt; "------------------------------------------------------------" &lt;&lt; std::endl;
      std::cout &lt;&lt; "Entering region 2:" &lt;&lt; std::endl;
  
  
      #pragma omp parallel
      {
          #pragma omp critical
          std::cout &lt;&lt; "num: "&lt;&lt; omp_get_thread_num() &lt;&lt; " =&gt; tid: " &lt;&lt; syscall(__NR_gettid) &lt;&lt; std::endl;
      }
  
  
      return 0;
  }
  </code></pre>
  
  <p>Here is the output I get in CentOS 7, using GCC (5.2).</p>
  
  <pre><code>Entering region 1:
  num: 0 =&gt; tid: 625
  num: 5 =&gt; tid: 630
  num: 7 =&gt; tid: 632
  num: 11 =&gt; tid: 636
  num: 3 =&gt; tid: 628
  num: 13 =&gt; tid: 638
  num: 1 =&gt; tid: 626
  num: 9 =&gt; tid: 634
  num: 6 =&gt; tid: 631
  num: 10 =&gt; tid: 635
  num: 12 =&gt; tid: 637
  num: 2 =&gt; tid: 627
  num: 4 =&gt; tid: 629
  num: 8 =&gt; tid: 633
  num: 14 =&gt; tid: 639
  num: 15 =&gt; tid: 640
  ------------------------------------------------------------
  Entering region 2:
  num: 4 =&gt; tid: 629
  num: 12 =&gt; tid: 637
  num: 15 =&gt; tid: 640
  num: 5 =&gt; tid: 630
  num: 8 =&gt; tid: 633
  num: 13 =&gt; tid: 638
  num: 0 =&gt; tid: 625
  num: 9 =&gt; tid: 634
  num: 1 =&gt; tid: 626
  num: 6 =&gt; tid: 631
  num: 3 =&gt; tid: 628
  num: 7 =&gt; tid: 632
  num: 10 =&gt; tid: 635
  num: 11 =&gt; tid: 636
  num: 2 =&gt; tid: 627
  num: 14 =&gt; tid: 639
  </code></pre>
  
  <p>Compilation: <code>g++ toy.cpp -fopenmp</code></p>