[英]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.