簡體   English   中英

openmp中帶有嵌套循環的並行部分代碼

[英]Parallel sections code with nested loops in openmp

我制作了這個並行代碼來共享迭代,例如 first 和 last、first+1 和 last-1,... 但是我不知道如何改進兩個並行部分中的每個部分的代碼,因為我有一個內部循環在這些部分中,我想不出任何方法來簡化它,謝謝。

這與將哪些值存儲在 x 或 y 中無關,我使用此部分設計,因為必要條件是執行從 0 到 N 的迭代,例如:0 N、1 N-1、2 N-2 但我想知道如果我可以優化維護這個 model 的內部循環

int x = 0, y = 0,k,i,j,h;
#pragma omp parallel private(i, h) reduction(+:x, y)
    {
            #pragma omp sections
            {
                    #pragma omp section
                    {
                            for (i=0; i<N/2; i++)
                            {
                                    C[i] = 0;
                                    for (j=0; j<N; j++)
                                    {
                                        C[i] += MAT[i][j] * B[j];
                                    }
                                    x += C[i];
                            }
                    }
                    #pragma omp section
                    {
                            for (h=N-1; h>=N/2; h--) 
                            {
                                    C[h] = 0;
                                    for (k=0; k<N; k++)
                                    {
                                        C[h] += MAT[h][k] * B[k];
                                    }
                                    y += C[h];
                            }
                    }
            }
    }
    x = x + y;

部分構造是將不同的任務分配給不同的線程,每個部分塊標記一個不同的任務,因此您將無法按照您想要的順序進行迭代我在這里回答您:

具有特定順序的線程之間的循環迭代分布

但我想澄清一下,使用節的要求是每個塊必須獨立於其他塊。

使用部分似乎是錯誤的方法。 一個pragma omp for似乎更合適。 另請注意,您忘記將j聲明為私有。

int x = 0, y = 0,k,i,j;
#pragma omp parallel private(i,j) reduction(+:x, y)
{
#   pragma omp for nowait
    for(i=0; i<N/2; i++) {
        // local variable to make the life easier on the compiler
        int ci = 0;
        for(j=0; j<N; j++)
            ci += MAT[i][j] * B[j];
        x += ci;
        C[i] = ci; 
    }
#   pragma omp for nowait
    for(i=N/2; i < N; i++) {
        int ci = 0;
        for(j=0; j<N; j++)
            ci += MAT[i][j] * B[j];
        y += ci;
        C[i] = ci;
    }
}
x = x + y;

另外,我不確定,但如果您只想將x作為您的最終 output,您可以進一步簡化代碼:

int x=0, i, j;
#pragma omp parallel for reduction(+:x) private(i,j)
for(i=0; i < N; ++i)
    for(j=0; j < N; ++j)
        x += MAT[i][j] * B[j];

一個部分只有一個線程,所以你不能使循環並行。 怎么樣

  1. 在頂層對N做一個並行循環,
  2. 然后在每次迭代中使用條件來決定是否累積到x,y

盡管@Homer512 的解決方案對我來說也是正確的。

暫無
暫無

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

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