我试图在我的程序中并行化一个循环,所以我搜索了多线程。首先,我看了一下POSIX多线程编程教程,它太复杂了,所以我试着做一些更简单的事情。我试过OpenMP。我已经成功并行化了我的代码,但执行时间问题比串行案例更糟糕。这低于我的程序的一部分。我希望你告诉我这是什么问题。我应该指定共享哪些变量以及哪些变量是私有的?我怎么知道每个变量的种类?我希望你回答我,因为我在许多论坛上搜索过,但我仍然不知道该怎么做。
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <omp.h>
#define D 0.215 // magnetic dipolar constant
main()
{
int i,j,n,p,NTOT = 1600,Nc = NTOT-1;
float r[2],spin[2*NTOT],w[2],d;
double E,F,V,G,dU;
.
.
.
for(n = 1; n <= Nc; n++){
fscanf(voisins,"%d%d%f%f%f",&i,&j,&r[0],&r[1],&d);
V = 0.0;E = 0.0;F = 0.0;
#pragma omp parallel num_threads(4)
{
#pragma omp for schedule(auto)
for(p = 0;p < 2;p++)
{
V += (D/pow(d,3.0))*(spin[2*i-2+p]-w[p])*spin[2*j-2+p];
E += (spin[2*i-2+p]-w[p])*r[p];
F += spin[2*j-2+p]*r[p];
}
}
G = -3*(D/pow(d,5.0))*E*F;
dU += (V+G);
}
.
.
.
}//End of main()
答案 0 :(得分:2)
您只使用2次迭代并行化循环:p=0
和p=1
。 OpenMP&#39;} omp for
的工作方式是将并行团队中的线程(您已定义为4个线程)之间的循环迭代分开,让他们解决问题的一部分并行。
只需2次迭代,你的2个线程将处于空闲状态。最重要的是,实际上找出哪些线程可以解决问题的哪一部分需要开销。如果你的实际循环不需要很长时间(在这种情况下它显然不会),那么开销将比你从并行化中获得的好处花费更多。
更好的策略通常是尽可能将最外层循环与OpenMP并行化,以便解决均匀分割工作和减少(相对)开销的问题。或者,您可以使用OpenMP 4.0的omp simd
命令在最低循环级别进行并行化。
最后,您没有正确计算变量V
,E
和F
。因为它们是从迭代到迭代的总和,所以您应该将它们全部定义为具有reduction(+:V)
的简化变量。如果你现在得到正确答案,我会感到惊讶。
(同样,高性能标记说:确保您为计划的执行时间执行计时,而不是计划的CPU时间执行。这通常使用omp_get_wtime()
完成。)