我有以下雙回圈,用于計算 matrix 的元素Fisher_M[FX][FY]。我試圖通過放置 OMP pragma 來優化它,#pragma omp parallel for schedule(dynamic, num_threads)但增益沒有預期的那么好。
有沒有辦法使用 OpenMP(總和)進行減少以快速計算元素Fisher_M[FX][FY]?或者也許這對 MAGMA 或 CUDA 可行?
#define num_threads 8
#pragma omp parallel for schedule(dynamic, num_threads)
for(int i=0; i<CO_CL_WL.size(); i ){
for(int j=0; j<CO_CL_WL.size(); j ){
if( CO_CL_WL[i][j] != 0 || CO_CL_WL_D[i][j] != 0){
Fisher_M[FX][FY] = CO_CL_WL[i][j]*CO_CL_WL_D[i][j];
}
}
}
uj5u.com熱心網友回復:
您的代碼在 line 處存在競爭條件Fisher_M[FX][FY] = ...。可以用歸約來解決:
double sum=0; //change the type as needed
#pragma omp parallel for reduction( :sum)
for(int i=0; i<CO_CL_WL.size(); i ){
for(int j=0; j<CO_CL_WL.size(); j ){
if( CO_CL_WL[i][j] != 0 || CO_CL_WL_D[i][j] != 0){
sum = CO_CL_WL[i][j]*CO_CL_WL_D[i][j];
}
}
}
Fisher_M[FX][FY] = sum;
請注意,此代碼受記憶體限制,計算成本不高,因此并行化的性能增益可能小于預期(并且取決于您的硬體)。
ps:為什么需要這個條件if( CO_CL_WL[i][j] != 0 || CO_CL_WL_D[i][j] != 0)?如果它們中的任何一個為零,則總和不會改變。如果洗掉它,編譯器可以制作更好的矢量化代碼。
Ps2:schedule(dynamic, num_threads)子句中的第二個引數是塊大小,而不是使用的執行緒數。我建議在你的情況下洗掉它。如果要指定使用的執行緒數,請添加num_threads子句或使用omp_set_num_threads函式。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/317127.html
上一篇:什么時候從std::vector更改為std::unordered_set值得?
下一篇:C 中的名稱和變數有什??么區別
