簡體   English   中英

openmp共享還是什么都沒有。 私有與未初始化

[英]openmp shared or nothing. private vs uninitialized

這兩個openmp實現之間有區別嗎?

float dot_prod (float* a, float* b, int N)
{
float sum = 0.0;
#pragma omp parallel for shared(sum)
for (int i = 0; i < N; i++) {
  #pragma omp critical
  sum += a[i] * b[i];
  }
return sum;
}

和相同的代碼,但第4行沒有shared(sum),因為sum已被初始化?

#pragma omp parallel for
for(int = 0; ....)

在openmp中對private的相同問題:

void work(float* c, int N)
{
float x, y; int i;
#pragma omp parallel for private(x,y)
for (i = 0; i < N; i++)
{
  x = a[i]; y = b[i];
  c[i] = x + y;
  }
}

與沒有private(x,y)的情況相同,因為x和y未初始化?

#pragma omp parallel for 

這兩個openmp實現之間有區別嗎?

float dot_prod (float* a, float* b, int N)
{
  float sum = 0.0;
# pragma omp parallel for shared(sum)
  for (int i = 0; i < N; i++) {
    #pragma omp critical
    sum += a[i] * b[i];
  }
  return sum;
}

在openMP中,在並行作用域之外聲明的變量是shared ,除非將其顯式設置為private 因此,可以省略shared聲明。

但是您的代碼遠非最佳。 它可以工作,但是要比順序的相應對象慢得多,因為critical將強制進行順序處理,而創建關鍵的部分在時間上會產生很大的成本。

適當的實現將使用reduction

float dot_prod (float* a, float* b, int N)
{
  float sum = 0.0;
# pragma omp parallel for reduction(+:sum)
  for (int i = 0; i < N; i++) {
    sum += a[i] * b[i];
  }
  return sum;
}

減少操作會創建一個隱藏的局部變量,以在每個線程中並行累積,並且在線程銷毀之前將這些局部和在共享變量sum上進行原子加法。

在openmp中對private的相同問題:

void work(float* c, int N)
{
  float x, y; int i;
# pragma omp parallel for private(x,y)
  for (i = 0; i < N; i++)
  {
    x = a[i]; y = b[i];
    c[i] = x + y;
  }
}

默認情況下, xy是共享的。 因此,如果沒有private行為,其行為將是不同的(並且有錯誤,因為所有線程都將修改相同的全局訪問變量vars xy而無需原子訪問)。

與沒有private(x,y)的情況相同,因為x和y未初始化?

xy初始化無關緊要,重要的是聲明它們的位置。 為了確保正確的行為,必須將它們設置為私有,並且由於在循環中使用xy之前已設置它們,因此代碼是正確的。

暫無
暫無

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

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