[英]Printing without race conditions with OpenMP in C++
我正在嘗試使用 OpenMP 來加速我的代碼,但問題是我需要打印東西而且我不知道如何在沒有競爭條件的情況下打印它們。
我的代碼看起來像這樣:
int some_comp(int n){
/* some computation */
}
int main(){
cin >> n;
#pragma omp parallel for
for(int i=0; i<=n; i++){
cout << some_comp(i) << endl;
}
}
很容易看到(並且非常明顯)在打印結果的行中有一個競爭條件,並且每次運行都不同。
我想要做的是擺脫競爭條件並以某種方式連續打印所有內容,因為如果我沒有使用 OpenMP,它應該已經打印出來。
我想過使用某種向量或列表或其他一些數據結構並將所有結果保存在那里,但問題是 n<=2^64 所以向量/列表/其他東西需要太多的 memory。
任何想法將不勝感激。
如果要實現與串行情況相同的 output,這意味着 output 中的行的順序很重要,您可以使用 OpenMP 的ordered
功能:
#pragma omp parallel for schedule(static,1) ordered
for(int i=0; i<=n; i++){
int result = some_comp(i);
#pragma omp ordered
cout << result << endl;
}
這假設some_comp(i)
與同步有序執行所花費的時間相比需要相對較長的計算時間。 你可以在這里閱讀更多關於它是如何工作的。
如果some_comp(i)
與 I/O 相當或更快,那么將數據存儲在緩沖區中並在之后按順序打印它是有意義的:
std::vector<int> results(n);
#pragma omp parallel for
for (int i=0; i<=n; i++){
results[i] = some_comp(i);
}
for (auto res : results){
cout << res << endl;
}
如果n
很大並且您沒有那么多空間來存儲大量結果值向量,只需將迭代空間分成塊:
const int chunk_size = 1000;
std::vector<int> results(chunk_size);
for (int chunk = 0; chunk < (n+1 + chunk_size) / chunk_size; chunk++) {
const int chunk_start = chunk * chunk_size;
const int i_max = std::min(n+1 - chunk_start, chunk_size);
#pragma omp parallel for
for (int i = 0; i < i_max; i++){
results[i] = some_comp(chunk_start + i);
}
for (int i = 0; i < i_max; i++){
cout << results[i] << endl;
}
}
我希望我所有的數學都是正確的,並且當chunk_size
除以n+1
和不除時,這都應該有效。
也可以將所有代碼放在一個並行區域中,以防止多個並行區域的開銷,並為順序部分使用single
構造,但如果您選擇適當的塊大小,不會有太多執行時間的差異,並且代碼像現在一樣更具可讀性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.