簡體   English   中英

OpenMp:如何使維度 std::vector 線程私有

[英]OpenMp: How to make dimensional std::vector threadprivate

我是 OpenMp 世界的新手,遇到了一個我無法修復的錯誤。 原來的代碼有點大,所以我做了一個小代碼來總結問題:

我得到了一個更維的std::vector (2d 和 3d),它不應該在線程之間共享。 如果我將它們標記為私有,它們仍然會導致內存錯誤,因為線程仍然共享它們。

我想出了一個解決這個問題的方法:我為 2d 向量創建了另外 1 個維度,這樣每個線程都可以訪問自己的副本:

myVector[omp_get_thread_num()][1].push_back(i);

我知道這不是解決我的問題的明智之舉,但現在每個線程都有自己的 2d Vector 副本。 現在出現了奇怪的部分:如果我不將#pragma omp critial放在它前面,有時這仍然會導致內存崩潰。 我真的不明白為什么有必要,因為線程不應該訪問相同的內存。

#include <iostream>
#include <omp.h>
#include <vector>

//this should represent my problem(without my fix)
int main(){
        std::vector < std::vector < int > > v;
    v.resize(3);

    #pragma omp parallel for num_threads(2) private(v)
    for(int i = 0; i < 10; i++){
            v[1].push_back(i); 
    }
    return 0;
}

我希望有更好的解決方案來使我的 2d 矢量線程私有。

附: 不可能在 omp 部分內分配向量。

您必須了解來自外部作用域的變量被聲明為private工作,就好像它們是在沒有初始化程序的情況下在本地聲明的一樣 所以每個本地副本都是一個空向量,因此您的代碼無法工作。

通常,OpenMP 最好在本地聲明私有變量 - 這樣可以避免根本沒有連接的“外部值”和“內部私有值”之間的很多混淆。 您可以通過拆分parallelfor指令來做到這一點。

#pragma omp parallel
{
    std::vector<std::vector<int>> v;
    v.resize(3);
    #pragma omp for
    for(int i = 0; i < 10; i++){
        v[1].push_back(i); 
    }
}

請注意,在並行區域之后v不可用 - 這很好! 在您的原始示例中, v在並行區域之后可用 - 但它的值與內部線程的值無關。

如果您需要保留來自v的信息,您可能需要考慮減少,但這取決於您的特定用例。

您的myVector[omp_get_thread_num()]是一種常見的幼稚方法。 此代碼是正確的,但在任何情況下修改最外層 vector 的值時,都會由於錯誤共享而導致性能不佳

myVector[omp_get_thread_num()].push_back(); // Bad performance
myVector[omp_get_thread_num()][1].push_back(i); // Ok

所以通常建議不要這樣做,而是使用本地聲明的變量。 然而,如果你的這段代碼崩潰了,那就是還有其他問題。 在這種情況下,您需要准備一個最小的可重現示例,並請提出第二個問題(參考此)。

現在threadprivateprivate不同。 private通常是你想要的,指的是特定的任務/范圍。 在大多數情況下,您不需要也不想要threadprivate

您可以使用 thread_local 存儲說明符:

int main(){
   thread_local std::vector < std::vector < int > > v;
   // ...
}

您沒有指定有關原始代碼的許多重要細節。 但是,一種方法可能是首先創建一個並行部分並在其中定義私有向量,然后並行化循環。 對於您的示例代碼,它可能如下所示:

int main() {
   #pramga omp parallel
   {
      std::vector<std::vector<int>> v;
      v.resize(3);

      #pragma omp for 
      for (int i = 0; i < 10; i++)
         v[1].push_back(i); 
   }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM