2017-09-04 84 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將爲每個線程重新初始化,而不是從任何其他線程複製。

如果你需要一個初始化爲一組值的數組的線程本地副本,你將必須確保將值放在那裏的操作(初始化或賦值)在每個線程中執行。