我有這個系列代碼:
for (i=0; i<N; i )
{
printf ("\n% i = d\n", i);
C[i] = 0;
for (j=0; j<N; j ) C[i] = MAT[i][j] * B[j];
x = C[i];
}
我想讓并行版本是一項簡單的任務,只有一個 pragma 并行,但困難的是分配迭代執行順序的規范,例如:
i = 0
i = n
i = 1
i = n-1
//The rest of iterations
如果我知道使用的執行緒數,我可以制作一個并行版本,但它必須使用任意偶數個執行緒列印該訂單我知道我必須使用 omp_get_num_threads 來跟蹤它,但我無法做到,謝謝
uj5u.com熱心網友回復:
我看到的問題是,如果你想像這樣分配迭代:0123...3210(數字是執行緒,位置是迭代)你必須修改回圈,因為我看到你不能如果您不跟蹤 Ni-1 迭代,則代碼將如下所示:
#pragma omp parallel for private (i, j, k) reduction( :x)
for (i=0; i<N/2; i )
{
k = N-1-i;
printf ("\n i = %d ", i);
printf ("\n k = %d\n", k);
C[i] = 0;
C[k] = 0;
for (j=0; j<N; j )
{
C[i] = MAT[i][j] * B[j];
C[k] = MAT[k][j] * B[j];
}
x = C[i];
x = C[k];
}
因此,同一個執行緒將執行 0 和 N,下一個執行緒 1 和 N-1...您甚至可以在每個回圈的更多執行中分配迭代,但請記住,分配的數量應該 <=N
如果你想保留順序:0 N, 1 N-1... 你必須使用子句ordered 和ordered block 但這對并行化沒有意義,因為不同的執行緒并發執行直到它們遇到有序區域然后它們以與在串行版本中執行的順序相同的順序順序執行這部分,但是增加了執行緒之間同步的過載時間,并且您將以串行版本的較慢版本結束。
#pragma omp parallel for ordered private (i, j, k) reduction( :x)
for (i=0; i<N/2; i )
{
#pragma omp ordered
k = N-1-i;
printf ("\n i = %d ", i);
printf ("\n k = %d\n", k);
C[i] = 0;
C[k] = 0;
for (j=0; j<N; j )
{
C[i] = MAT[i][j] * B[j];
C[k] = MAT[k][j] * B[j];
}
x = C[i];
x = C[k];
}
我想 N 總是甚至是由于您想要進行的分布型別,但如果不是這種情況,您可以在for之后添加它以執行中間的術語的操作,因為盡管我還沒有嘗試過,我想這如果按順序它會比并行內部消耗更少的時間,因為只是因為它是要處理的最后一個元素,而且您似乎不想并行化內部回圈。
if(N%2 != 0)
{
i = N/2;
C[i] = 0;
for (j=0; j<N; j )
{
C[i] = MAT[i][j] * B[j];
}
x = C[i];
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/399156.html
