當我讀取還原變量的初始值是根據用於還原的運算符設置後,我決定不是記住這些默認值,而是顯式初始化它。所以我修改了代碼中question by Totonga如下OpenMP:無法更改還原變量的值
const int num_steps = 100000;
double x, sum, dx = 1./num_steps;
#pragma omp parallel private(x) reduction(+:sum)
{
sum = 0.;
#pragma omp for schedule(static)
for (int i=0; i<num_steps; ++i)
{
x = (i+0.5)*dx;
sum += 4./(1.+x*x);
}
}
但事實證明,無論是否我寫總和= 0或總和= 123.456碼產生相同的結果(用gcc-4.5.2編譯器)。請有人解釋我爲什麼? (如果可能,參考openmp標準)提前感謝大家。
P.S.因爲有些人反對初始化還原變量,所以我認爲稍微擴展一個問題是有意義的。如預期下面作品代碼:I初始化減小變量和得到的結果,這不依賴於MY初始值
int sum;
#pragma omp parallel reduction(+:sum)
{
sum = 1;
}
printf("Reduction sum = %d\n",sum);
打印結果將是我有核的數量,並且不爲0。
PPS再次更新我的問題。用戶Gilles給出了一個有見地的評論:並且在並行區域退出時,在進入該部分之前,將使用+運算符和變量的初始值來減少這些局部值。
好了,下面的代碼給我的結果3.142592653598146
,這是不好計算pi
,而不是預期103.141592653598146
(初始密碼是給我的pi=3.141592653598146
卓越的價值)
const int num_steps = 100000;
double x, sum, dx = 1./num_steps;
sum = 100.;
#pragma omp parallel private(x) reduction(+:sum)
{
#pragma omp for schedule(static)
for (int i=0; i<num_steps; ++i)
{
x = (i+0.5)*dx;
sum += 4./(1.+x*x);
}
}
我想你正在尋找最新OpenMP規範的第2.14.3.6條。只要你需要關心,每個線程都會得到一個被稱爲「sum」的私有變量,它被初始化爲「+」,爲0。你嘗試初始化'sum'到其他值是徒勞的。 –
如果您很難記住OpenMP初始化還原變量的值,請記住只有一個*還原操作*的標識元素。 –
我不明白爲什麼你不喜歡這麼多,我試圖初始化一個變量,並且同時對於我以後在這個變量上做的操作也沒問題。對於程序員來說,這是非常正常的行爲 - 初始化然後操作變量。還原條款向我保證,當我退出平行部分時,它會將所有私人副本收集到一個副本中,但我不明白在哪一點上可以改變它的價值。 –