我有两个非常简单的代码。我试图将它们并行如下:
double sk = 0, ed = 0;
#pragma omp parallel shared(Z,Zo,U1,U2,U3) private(i) reduction(+: sk, ed)
{
#pragma omp for
for (i=0;i<imgDim;i++)
{
sk += (Z[i]-Zo[i])*(Z[i]-Zo[i]);
ed += U1[i]*U1[i] + U2[i]*U2[i] + U3[i]*U3[i];
}
}
///////////////////////////////////////// ///////////////////////////////
double rk = 0, epri = 0, ex = 0, ez = 0;
#pragma omp parallel shared(X,Z) private(i) reduction(+: rk, ex,ez)
{
#pragma omp for
for(i = 0; i<imgDim; i++)
{
rk += (X[0][i]-Z[i])*(X[0][i]-Z[i]) + (X[1][i]-Z[i])*(X[1][i]-Z[i]) + (X[2][i]-Z[i])*(X[2][i]-Z[i]);
ex += X[0][i]*X[0][i] + X[1][i]*X[1][i] + X[2][i]*X[2][i];
ez += Z[i]*Z[i];
}
}
Z、Zo、U1、U2、U3、X 都是大矩阵。imgDim 是 400 万。速度没有想象中那么快。在一台16核的机器上,这两条小代码的速度只有两倍。我不明白为什么 OMP 会出现这种行为,因为这两个代码只是加起来而已。这应该是OMP擅长的。
更奇怪的行为是,当我尝试使用 MPI 并行这些代码时,MPI 会减慢速度,如下所示:
int startval = imgDim*pid/np;
int endval = imgDim*(pid+1)/np-1;
int ierr;
double p_sum_sk = 0;
double p_sum_ed = 0;
for (i=startval;i<=endval;i++)
{
sk += (Z[i]-Zo[i])*(Z[i]-Zo[i]);
ed += U1[i]*U1[i] + U2[i]*U2[i] + U3[i]*U3[i];
}
MPI_Reduce(&sk, &p_sum_sk, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce(&ed, &p_sum_ed, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Bcast(&sk, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Bcast(&ed, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
///////////////////////////////////////// //////////////////////////////
int startval = imgDim*pid/np;
int endval = imgDim*(pid+1)/np-1;
double p_sum_rk = 0.;
double p_sum_ex = 0.;
double p_sum_ez = 0.;
for(i = startval; i<=endval; i++)
{
rk = rk + (X[0][i]-Z[i])*(X[0][i]-Z[i]) + (X[1][i]-Z[i])*(X[1][i]-Z[i]) + (X[2][i]-Z[i])*(X[2][i]-Z[i]);
ex += X[0][i]*X[0][i] + X[1][i]*X[1][i] + X[2][i]*X[2][i];
ez += Z[i]*Z[i];
}
MPI_Reduce(&rk,&p_sum_rk,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
MPI_Reduce(&ex,&p_sum_ex,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
MPI_Reduce(&ez,&p_sum_ez,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
MPI_Bcast(&rk,1,MPI_INT,0,MPI_COMM_WORLD);
MPI_Bcast(&rk,1,MPI_INT,0,MPI_COMM_WORLD);
MPI_Bcast(&epri,1,MPI_INT,0,MPI_COMM_WORLD);
np 是处理器的数量,pid 是当前处理器的 id。在我使用 32 甚至 64 处理器后,它并没有显示出任何加速。它甚至比顺序代码还要慢。我不懂为什么。这些代码只是在添加东西。OMP 和 MPI 应该擅长它。谁能帮我一把?