2017-09-04 118 views
1

我试图使用open_MP并使用omp prallel for,但我遇到了一个问题。静态变量thread_local与open_MP

我用了很多不同的静态类成员的像

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

,我在我的.cpp文件的空载体初始化。

一段时间后,我做了一些计算,终于充盈了我的初始值向量v:

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

一段时间后,我有一个大的循环可能(但不得)改变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; 
} 

我的问题是现在,当我进入平行于环路我的矢量V不再是{1,2,3},那简直是空的。

我该如何改变这种情况?我认为在开始时v是“主线程”的本地线程,而新创建的“子线程”并没有获得关于v。 的信息有没有办法轻松解决这个问题?或者我需要为每个线程初始化v? (这将不会很大,因为初始化需要相当长的时间,这是不可能的(但有可能),我需要改变每个for循环的参数)

+0

在我看来,如果你想用OpenMP来抽象程序的并行部分,你应该避免使用TLS。不应该更容易将矢量声明为私有?你真的需要私有化吗?您可能只需确保对向量元素的访问是线程安全的(即不要修改向量的元素数量)。您提供的有关并行循环的信息不足以帮助您。尝试提供[最小化,完整且可验证的]示例(https://stackoverflow.com/help/mcve),以确保我们理解您想要解决的问题。 –

+0

另请参见[OpenMP和std :: vector的缩减](https://stackoverflow.com/a/43169193/5809597) –

回答

1

如果你写一个初始化

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

您将在所有主题中获得v的副本,其中包含{1,2,3}。但是,如果你写一个分配

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

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

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