簡體   English   中英

OpenMP 中的並行編程

[英]parallel programming in OpenMP

我有以下一段代碼。

for (i = 0; i < n; ++i) {
  ++cnt[offset[i]];
}

其中offset是一個大小為n的數組,其中包含[0, m)范圍內的值,而cnt是一個大小為m的數組,初始化為 0。我使用 OpenMP 對其進行並行化,如下所示。

#pragma omp parallel for shared(cnt, offset) private(i)
for (i = 0; i < n; ++i) {
  ++cnt[offset[i]];
}

根據這篇文章的討論,如果offset[i1] == offset[i2] for i1 != i2 ,上面的代碼可能會導致錯誤的cnt 我能做些什么來避免這種情況?

這段代碼:

#pragma omp parallel for shared(cnt, offset) private(i)
for (i = 0; i < n; ++i) {
  ++cnt[offset[i]];
}

在數組cnt更新期間包含競爭條件,要解決它,您需要保證這些更新的互斥。 這可以通過(例如) #pragma omp atomic update來實現,但正如評論中已經指出的那樣:

但是,這僅解決了正確性問題,並且由於大量的緩存爭用和同步需求(包括錯誤共享),可能效率非常低。 唯一的解決方案是讓每個線程擁有其私有的 cnt 副本,並在最后減少這些副本。

另一種解決方案是每個線程都有一個私有數組,並在並行區域結束時手動將所有這些 arrays 減少為一個。 可以在此處找到此類方法的示例。

幸運的是,使用OpenMP 4.5 ,您可以使用專用 pragma 減少 arrays,即:

#pragma omp parallel for reduction(+:cnt)

您可以查看此示例以了解如何應用該功能。

值得一提的是,關於減少 arrays@Jérôme Richard所指出的原子方法相比:

請注意,僅當數組不是很大時,這才很快(在這種關於平台的特定情況下,如果值不沖突,基於原子的解決方案可能會更快)。 所以這是 m << n。

一如既往,分析是關鍵;因此。 您應該使用上述方法測試您的代碼,以找出最有效的方法。

暫無
暫無

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

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