OPENMP并行程序,并行之后与串行耗时总是差不多
自己用C写了一个电网短路计算的程序,因为不同时发生的短路之间不会互相影响,所以自己就想用OPENMP+for循环并行计算每次短路的短路电流。可是用了之后发现和串行的总时间总是差不多,查看输出结果确实实现了多条线程运行。当设置两线程时,每次循环的时间就是串行每次循环的两倍;当设置四线程时,每次循环的时间就是串行每次循环的四倍,几乎使得每次并行循环与每次串行循环时间的比值就是设置的线程数,这样并行的总时间和串行的总时间几乎就差不多。。。。好蛋疼,求大神帮帮忙!并行部分如下所示:
#pragma omp parallel num_threads(4) default(shared)
{
#pragma omp for schedule(dynamic) private(i,j,z,a,b,k,p,y,II0,II1,II2,II,Za1,Zb1,Za0,Zb0,j1,j2,j3,j4,tb,yg,yf,III,If,Vf)
firstprivate(Y_a,Y_b,Y_c,I0,n)
for(t=0;t<net[0].m_duanlus;t++)
{
clock_t begin,duration;
a=Dl[t].m_headindex;
b=Dl[t].m_tailindex;
for(i=0;i<3*(n+2);i++) //数组yf[i][j]初始化
{
for(j=0;j<3*(n+2);j++)
yf[i][j]=0;
}
for(i=0;i<3*(n+2);i++) //数组yg[i][j]初始化
{
for(j=0;j<3*(n+2);j++)
yg[i][j]=0;
}
for(i=0;i<3*(n+2);i++) //数组III[i][j]初始化
{
for(j=0;j<3*(n+2);j++)
III[i][j]=0;
}
begin=clock();
if (Dl[t].m_isonbus==1) //母线处发生短路故障
{
p=Dl[t].m_headindex; //故障母线编号
z=0; //新增节点数
for(i=0;i<(n+z);i++)
for(j=0;j<(n+z);j++)
yf[i][j]=Y_a[i][j];
for(i=(n+z);i<2*(n+z);i++)
for(j=(n+z);j<2*(n+z);j++)
yf[i][j]=Y_b[i-(n+z)][j-(n+z)];
for(i=2*(n+z);i<3*(n+z);i++)
for(j=2*(n+z);j<3*(n+z);j++)
yf[i][j]=Y_c[i-(2*(n+z))][j-(2*(n+z))];
for(i=0;i<3*(n+z);i++)
{
for(j=0;j<3*(n+z);j++)
yg[i][j]=yf[i][j];
}
// =1:a相短路接地; =2:b相短路接地; =3:b相短路接地;
// =4:ab相间短路; =5:bc相间短路; =6:ac相间短路;
// =7: ab相间短路接地;=8:bc相间短路接地; =9: ac相间短路接地;
// =10:三相短路;=11:三相短路接地
for(i=0;i<3*(n+z);i++)
If[i]=I0[i];
switch (Dl[t].m_biaoshi)
{
case 1:
case 2:
case 3:
{
y=1/Dl[t].m_Xn;
yf[a-1][a-1]+=(y/3);
yf[n+a-1][n+a-1]+=(y/3);
yf[2*n+a-1][2*n+a-1]+=(y/3);
yf[a-1][n+a-1]+=(y/3);
yf[a-1][2*n+a-1]+=(y/3);
yf[n+a-1][2*n+a-1]+=(y/3);
yf[n+a-1][a-1]+=(y/3);
yf[2*n+a-1][a-1]+=(y/3);
yf[2*n+a-1][n+a-1]+=(y/3);
}
break;
case 4:
case 5:
case 6:
{
。。。。。
}
break;
case 7:
case 8:
case 9:
{
。。。。。。。
}
break;
case 10:
{
。。。。。。
}
break;
case 11:
{
。。。。。。
}
break;
} //end switch
}
if (Dl[t].m_isonbus==0) //非母线处发生短路故障
{
p=n+1; //短路点编号
z=1; //新增节点数
for(i=0;i<(n+z);i++)
for(j=0;j<(n+z);j++)
yf[i][j]=Y_a[i][j];
for(i=(n+z);i<2*(n+z);i++)
for(j=(n+z);j<2*(n+z);j++)
yf[i][j]=Y_b[i-(n+z)][j-(n+z)];
for(i=2*(n+z);i<3*(n+z);i++)
for(j=2*(n+z);j<3*(n+z);j++)
yf[i][j]=Y_c[i-(2*(n+z))][j-(2*(n+z))];
Za1=-Dl[t].m_pos/Y_a[a-1][b-1];
Zb1=-(1-Dl[t].m_pos)/Y_a[a-1][b-1];
Za0=-Dl[t].m_pos/Y_c[a-1][b-1];
Zb0=-(1-Dl[t].m_pos)/Y_c[a-1][b-1];
yf[a-1][a-1]=Y_a[a-1][a-1]+Y_a[a-1][b-1]+1/Za1;
yf[b-1][b-1]=Y_a[b-1][b-1]+Y_a[a-1][b-1]+1/Zb1;
yf[n][n]=(1/Za1)+(1/Zb1);
yf[n][a-1]=yf[a-1][n]=-1/Za1;
yf[n][b-1]=yf[b-1][n]=-1/Zb1;
yf[b-1][a-1]=yf[a-1][b-1]=-MIN_X;
。。。。。。。。。。。。
for(i=0;i<3*(n+z);i++)
{
for(j=0;j<3*(n+z);j++)
yg[i][j]=yf[i][j];
}
for(i=0;i<3*(n+z);i++)
If[i]=I0[i];
// =1:a相短路接地; =2:b相短路接地; =3:b相短路接地;
// =4:ab相间短路; =5:bc相间短路; =6:ac相间短路;
// =7: ab相间短路接地;=8:bc相间短路接地; =9: ac相间短路接地;
// =10:三相短路;=11:三相短路接地
switch (Dl[t].m_biaoshi)
{
case 1:
case 2:
case 3:
{
。。。。。。。
}
break;
case 4:
case 5:
case 6:
{
。。。。。
}
break;
case 7:
case 8:
case 9:
{
。。。。。。
}
break;
case 10:
{
。。。。。。。。
}
break;
case 11:
{
。。。。。。
}
break;
} //end switch
}
//解网络方程
for(k=0;k<(3*(n+z)-1);k++)
for(i=(k+1);i<(3*(n+z));i++)
{
If[i]=If[i]-(yf[i][k]*If[k]/yf[k][k]);
for(j=(k+1);j<(3*(n+z));j++)
yf[i][j]=yf[i][j]-(yf[i][k]*yf[k][j]/yf[k][k]);
yf[i][k]=0;
}
printf("\n**************高斯消元后的矩阵yf****************\n");
for(i=0;i<(3*(n+z));i++)
{
for(j=0;j<(3*(n+z));j++)
printf("%f ",yf[i][j]);
printf("\n");
}
printf("\n**************高斯消元后的矩阵If****************\n");
for(i=0;i<(3*(n+z));i++)
printf("%f ",If[i]);
//反向迭代求Vf
Vf[3*(n+z)-1]=If[3*(n+z)-1]/yf[3*(n+z)-1][3*(n+z)-1];
for(i=(3*(n+z)-2);i>=0;i--)
{
for(k=(i+1);k<=3*(n+z)-1;k++)
If[i]=If[i]-(yf[i][k]*Vf[k]);
Vf[i]=If[i]/yf[i][i];
}
printf("\n\n**************节点三序电压矩阵Vf****************\n");
for(i=0;i<(3*(n+z));i++)
printf("%f ",Vf[i]);
}
是不是私有变量太多了,可是少了,计算结果就有问题了。还是电脑内存带宽不够。。。。。。跪求大神指教啊!