omp_get_thread_num是如何实现的?

时间:2014-04-09 10:28:01

标签: openmp

我很好奇它是如何工作的,因为这个函数是在没有参数的情况下调用的,它如何找出实际调用它的线程?

2 个答案:

答案 0 :(得分:1)

以下内容特定于GNU的OpenMP运行时库libgomp,但其他OpenMP运行时或多或少相同。所有链接都指向GCC 4.8.2源代码的相关部分。

omp_get_thread_num()的实际实施非常简单:

int
omp_get_thread_num (void)
{
  return gomp_thread ()->ts.team_id;
}

每个线程都有一个指向struct gomp_thread实例的线程局部指针。此外,每个线程都是线程团队的一部分,团队中的状态由struct gomp_thread_team_state类型的ts成员表示。后者包含一个名为unsigned int的{​​{1}}成员,该成员提供其团队中线程的ID。

线程找到自己的team_id实例的方式取决于平台是否具有TLS(线程本地存储)。在后一种情况下,TLS由POSIX线程库模拟。两种实现都是:(取自here

使用TLS:

struct gomp_thread

extern __thread struct gomp_thread gomp_tls_data; static inline struct gomp_thread *gomp_thread (void) { return &gomp_tls_data; } 关键字使全局变量__thread成为线程本地,这意味着每个线程都有自己的副本。

没有TLS:

gomp_tls_data

在这种情况下,extern pthread_key_t gomp_tls_key; static inline struct gomp_thread *gomp_thread (void) { return pthread_getspecific (gomp_tls_key); } 用于获取结构实例的线程局部副本(位于here)。

虽然pthread_getspecific()也可能使用TLS来存储值,但有人可能想知道为什么提供了两种不同的实现,答案是直接访问TLS可能比调用Pthreads API函数更快。在这方面,OS X是一个特殊的情况 - Mach-O可执行格式不提供GNU兼容的TLS实现,有些人报告说Pthreads API实际上比模拟的GNU TLS更快。

答案 1 :(得分:0)

AFAIK,未指定,所以我无法给出一般答案。 GCC使用一种结构来管理线程,其中__thread attribute。我想其他编译器中的实现将是类似的。

文档链接到PDF,它解释了TLS(线程本地存储)的工作原理:http://www.akkadia.org/drepper/tls.pdf