【问题标题】:static variable thread_local with open_MP带有 open_MP 的静态变量 thread_local
【发布时间】:2017-09-04 12:31:17
【问题描述】:

我尝试使用 open_MP 并使用 omp prallel for,但遇到了问题。

我使用了很多不同的静态类成员,比如

class A {
public:
    static std::vector<double> v;
}

我在 .cpp 文件中使用一个空向量进行初始化。

一段时间后,我做了一些计算,最后用我的初始值填充向量 v:

A::v = {1,2,3};

一段时间后,我有一个大的 for 循环,它可以(但不能)再次改变 v 的值。

现在我尝试使用 open_MP 来加快速度:

#pragma omp parallel for
for (int i = 0; i < nsched; ++i) {
    ...
}

因为我希望每个循环都有自己的静态向量实例,所以我只是尝试将其设为 thread_local。

class A {
public:
    static thread_local std::vector<double> v;
}

我现在的问题是,一旦我进入并行 for 循环,我的向量 v 不再是 {1,2,3},它只是空的。

我该如何改变呢?我假设一开始 v 是“主线程”的线程本地,并且新创建的“子线程”没有得到关于 v 的信息。 有没有办法轻松解决这个问题?还是我需要为每个线程初始化 v ? (这不会很好,因为初始化需要相当长的时间,而且我不太可能(但可能)需要更改每个 for 循环中的参数)

【问题讨论】:

  • 在我看来,如果你想用 OpenMP 抽象程序的并行部分,你应该避免使用 TLS。将向量声明为私有不是更容易吗?真的需要私有化吗?您可能只需要确保对向量元素的访问是线程安全的(即不要修改向量的元素数量)。您提供的有关并行循环的信息不足以帮助您。尝试提供minimal, complete and verifiable 示例,以确保我们了解您要解决的问题。

标签: c++ static openmp thread-local


【解决方案1】:

如果你写一个初始化

thread_local std::vector<double> A::v {1,2,3};

您将在所有线程中获得包含{1,2,3}v 副本。但是如果你写一个作业

A::v = {1,2,3};

你不会的。 A::v 将为每个线程重新初始化,而不是从任何其他线程复制。

如果您需要初始化为一组值的数组的线程本地副本,则必须确保在每个线程中执行将值放入其中的操作(初始化或赋值)。

【讨论】:

    猜你喜欢
    • 2014-05-12
    • 1970-01-01
    • 2016-04-27
    • 2012-03-28
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多