[英]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;
}
}
默認情況下, x
和y
是共享的。 因此,如果沒有private
行為,其行為將是不同的(並且有錯誤,因為所有線程都將修改相同的全局訪問變量vars x
和y
而無需原子訪問)。
與沒有private(x,y)的情況相同,因為x和y未初始化?
x
和y
初始化無關緊要,重要的是聲明它們的位置。 為了確保正確的行為,必須將它們設置為私有,並且由於在循環中使用x
和y
之前已設置它們,因此代碼是正確的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.