【问题标题】:OpenMP treat all static variables as threadprivate by defaultOpenMP 默认将所有静态变量视为线程私有
【发布时间】:2019-09-12 23:40:33
【问题描述】:

我有一个需要在多个输入上并行运行的 C 函数。

我正在尝试使用 OpenMP 来执行此操作,但问题是,我正在使用的函数正在使用一些内部静态变量进行自己的内部计算。

当尝试并行运行此函数的多个实例时,由于多个线程正在访问同一内存区域,程序会崩溃。

这可以通过将每个静态变量定义为“threadprivate”来解决,但是由于我有很多内部变量,这有点矫枉过正。

有没有办法让 OpenMP 默认将所有变量都视为“线程私有”?

【问题讨论】:

  • 我不认为允许编译器通过某种外部机制(例如编译器标志)将static 变量视为threadprivate 是一个好主意。这会使阅读此类代码的读者感到困惑。
  • ATM 对我来说无关紧要,因为我只是在我的测试代码上使用 OpenMP 只是为了让它运行得更快,而不是作为生产代码的一部分。
  • 为什么这个问题被标记为 C 和 C++?你实际使用的是什么?
  • @Zulan 我使用 C++ 运行我的测试(使用 Catch2 测试框架),而我正在测试的函数是用 C 编写的(这就是所有私有内部成员都是全局的原因)。

标签: c parallel-processing openmp


【解决方案1】:

没有这种可能。

不,你可以尝试一些冒险的#define static,但我强烈建议不要这样做。

事情是这样的。如果您将所有函数都替换为线程局部变量,则使用 static 的函数不会突然成为线程安全的。考虑:

int unique_number() {
    static i = 0;
    return i++; // surely this is unique!
}

如果你有跨调用捕获状态的函数,例如臭名昭​​著的strtok,情况会变得更糟:

my_threadlocal_strtok(str, ...);
#pragma omp parallel for
for () {
    my_threadlocal_strtok(NULL, ...); //
}

您必须考虑这个静态(或者现在是线程本地)状态的“生命周期”。

定义一堆以前是staticthreadlocal 变量会使推理并行代码变得更加困难,并且很可能会引入一些细微的错误。顺便说一下,全局变量也是如此,这也使得并行化变得更加困难。

最后,不要滥用static 来跨调用存储状态。而是对状态使用显式句柄。如果您希望透明地缓存 数据,而使用static 会失控。您可以考虑使用显式初始化/访问函数来抽象缓存的状态,然后这些函数更易于以线程安全/线程本地方式使用。这在 C++ 中比在 C 中容易得多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-08
    • 1970-01-01
    • 2013-10-09
    • 2014-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多