簡體   English   中英

OpenMP for C ++對象數組的循環

[英]OpenMP for loop on array of C++ objects

我正在運行一個模擬,其中生成許多隨機數。 RNG實現為C ++對象,其具有返回隨機數的公共方法。 為了將它與OpenMP並行化一起使用,我只需創建一個這樣的RNG對象數組,每個線程一個。 然后,每個線程通過調用其中一個RNG生成自己的隨機數。 例如:

  for (int i = 0; i < iTotThreads; i++) {
    aRNG[i] = new RNG();
  }
  // ... stuff here
#pragma omp parallel 
  {
    iT = omp_get_thread_num();
#pragma omp for
    for ( /* big loop */) {
      // more stuff
      aRNG[iT]->getRandomNumber();
      // more stuff
    }
  }  

即使每個RNG都在自己的成員變量上工作,並且兩個這樣的RNG不適合單個緩存行(我也嘗試在創建時明確地對齊它們),但由於代碼無法擴展,似乎存在一些錯誤的共享一點都不

如果我在omp並行區域內實例化對象:

#pragma omp parallel
  { 
    i = omp_get_thread_num();
    aRNG[i] = new RNG();
  }

代碼完美地擴展。 你知道我在這里缺少什么嗎?

編輯:順便說一句,在第二種情況下(縮放的那個),我創建RNG的並行區域與我使用它們的並行區域不同。 我指望當我進入第二個平行區域時, aRNG[]每個指針仍然指向我的一個對象,但我想這是不好的做法......

雖然我懷疑你的描述錯誤共享是導致問題的原因,但為什么不以這種方式簡化代碼:

  // ... stuff here
#pragma omp parallel 
  {
    RNG rng;
#pragma omp for
    for ( /* big loop */) {
      // more stuff
      rng.getRandomNumber();
      // more stuff
    }
  }

parallel區域內聲明rng將是具有自動存儲持續時間的私有變量,因此:

  • 每個線程都有自己的私有隨機數生成器(這里不允許虛假共享)
  • 您不必管理資源的分配/取消分配

如果這種方法不可行,並且遵循@HristoIliev的建議,您總是可以聲明一個threadprivate變量來保存指向隨機數生成器的指針:

static std::shared_pointer<RNG> rng;
#pragma omp threadprivate(rng);

並在第一個並行區域中分配它:

rng.reset( new RNG );

在這種情況下,雖然有一些注意事項可以確保跨越並行區域保留rng的值(引用OpenMP 4.0標准):

只有滿足以下所有條件時,才能保證非初始線程的threadprivate變量中的數據值保持在兩個連續的活動並行區域之間:

  • 並行區域都不嵌套在另一個顯式並行區域內。
  • 用於執行兩個並行區域的線程數相同。
  • 用於執行兩個並行區域的線程親和性策略是相同的。
  • 在進入兩個並行區域時,封閉任務區域中的dyn-var內部控制變量的值為false。

如果這些條件都成立,並且如果在兩個區域中引用了threadprivate變量,則在其各自區域中具有相同線程編號的線程將引用該變量的相同副本。

暫無
暫無

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

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