【问题标题】:OpenMP and Thread Local Storage identifier with iccOpenMP 和带有 icc 的线程本地存储标识符
【发布时间】:2013-11-14 14:57:15
【问题描述】:

这是一个简单的测试代码:

#include <stdlib.h>

__thread int a = 0;

int main() {

    #pragma omp parallel default(none)
    {
        a = 1;
    }

    return 0;
}

gcc 编译这个没有任何问题 -fopenmp,但是 icc (ICC) 12.0.2 20110112 和 -openmp 抱怨

test.c(7):错误:必须在包含 OpenMP 并行编译指示的变量列表中指定“a” #pragma omp 并行默认值(无)

我不知道哪种范例(即shared、private、threadprivate)适用于这种类型的变量。哪一种是正确的?

调用访问该线程局部变量的函数时,我得到了预期的行为,但我无法从显式并行部分中访问它。

编辑:

目前我最好的解决方案是通过函数返回指向变量的指针

static inline int * get_a() { return &a; }

【问题讨论】:

  • 混合不同的线程模型可能不是一个好主意。语义上threadprivate 可能是最接近的。由于__thread 是一个编译器扩展,您可能找不到很多将它与 OpenMP 链接的文档。
  • 您使用的是哪个编译器? GCC 不应要求您为 a 提供明确的数据共享类,即使指定了 default(none)。
  • @HristoIliev 我正在使用icc 12.0.2。你是对的,这似乎是icc 的问题。 gcc 接受这个。
  • 尝试在a声明后的下一行添加#pragma omp threadprivate(a)。这有点重言式,因为在很大程度上两者都做同样的事情(有一些关于 C++ 对象的例外情况)。
  • @HristoIliev 就是这个!摆脱__thread 说明符并改用#pragma omp threadprivate 甚至使我的代码与Mach-O 兼容,因为__thread 在Mach-O 可执行文件中不受支持。如果您将此作为答案发布,那么我很乐意为您提供信用。

标签: c openmp icc thread-local-storage


【解决方案1】:

__thread 大致类似于threadprivate OpenMP 指令的效果。在很大程度上(当不涉及 C++ 对象时读取),两者都经常使用相同的底层编译器机制实现,因此是兼容的,但这不保证总是工作。当然,现实世界远非理想,我们有时不得不牺牲可移植性,以使事情在给定的开发限制内工作。

threadprivate 是指令而不是子句,因此您必须执行以下操作:

#include "header_providing_a.h"

#pragma omp threadprivate(a)

void parallel_using_a()
{
   #pragma omp parallel default(none) ...
     ... use 'a' here
}

GCC(至少 4.7.1 版)将 __thread 视为隐含的 threadprivate 声明,您无需执行任何操作。

【讨论】:

  • 有趣的是:对于 Linux 上的 gcc,__thread 和 threadprivate 是同义词,在 x86 上使用 FS 段寄存器。在 OS X (Mach-O) 上,threadprivate 导致 gcc 使用一些名为 ___emutls_get_address 的仿真。对于 icc,在 Linux x86 上存在 __thread(与 threadprivate 无关)会导致与 gcc 相同的行为:使用 FS 段寄存器。在没有__thread 的情况下,但有了threadprivate,icc 会在 Linux 和 OS X 上进行一些相当复杂的仿真。
  • 将-openmp-threadprivate=compat 传递给icc 会导致它在兼容的操作系统/架构上以与__thread 相同的方式处理threadprivate。
  • @SergeyL。 threadprivate 的情况(变慢)是否在 MacOS 上有所改善?现在使用 GCC、ICC 或 Clang 会更好吗?我从来没有在 MacOS 上使用过 OpoenMP(就此而言,我从来没有用 macOS 编译过任何东西),但我只是好奇。 threadprivate 是否在 Linux 上使用 ICC 进行仿真?如果是,为什么?在 MacOS 上,带有 TLS 的 Mach-O 是否存在一些限制?
  • @Zboson,也许 Clang 的不同 TLS 模型对应于它默认使用的英特尔 OpenMP 运行时中的不同 TLS 实现。英特尔编译器具有相同的选项。
  • @Zboson,Intel OpenMP Runtime 很早以前就已经开源,它是 Clang 中 OpenMP 支持的基础。看到 IBM 的人也在从事这项工作真是太棒了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
相关资源
最近更新 更多