我一直试图并行化我编写的粒子模拟代码。但是在我的并行化中,当从1个处理器移动到12个时,我的性能没有提高,更糟糕的是代码不再返回准确的结果。我一直在撞墙撞墙,无法解决这个问题。下面是并行循环:
#pragma omp parallel
{
omp_set_dynamic(1);
omp_set_num_threads(12);
#pragma omp for
// Loop over azimuth ejection angle, from 0-360.
for(int i=0; i<360; i++)
{
// Declare temporary variables
double *y = new double[12];
vector<double> ejecVel(3);
vector<double> colLoc(7);
double azimuth, inc;
bool collision;
// Loop over inclincation ejection angle from 1-max_angle, increasing by 1 degree.
for(int j=1; j<=15; j++)
{
// Update azimuth and inclination angle and get velocity direction vector.
azimuth = (double) i;
inc = (double) j;
ejecVel = Jet::GetEjecVelocity(azimuth,inc);
collision = false;
// Update initial conditions.
y[0] = m_parPos[0];
y[1] = m_parPos[1];
... (define pointer values)
// Simulate particle
systemSolver.ParticleSim(simSteps,dt,y,collision,colLoc);
if(collision == true)
{
cout << "Collision! " << endl;
}
}
delete [] y;
}
目标是循环,在循环上模拟不同初始条件下的粒子,并在主变量densCount和collisionStates中存储它们已经消失的状态和碰撞时的状态向量。模拟发生在另一个类(systemSolver.ParticleSim())的函数中,似乎每个不同线程的求解都不是独立的。我读过的所有内容都表明它应该是,但我无法弄清楚为什么只有在我实施Open MP时结果才会正确。任何想法都非常感谢。
-ben
解决方案:模拟正在修改单独(systemSolver)类的成员变量。由于我为所有线程提供了单个类对象,因此它们同时修改了一个重要的成员变量。以为我会发布这个以防任何其他n00bs遇到类似的问题。
答案 0 :(得分:1)
我认为一个错误是在并行区域内调用omp_set_ *函数。在最好的情况下,它们仅对后续区域生效。尝试重新排序如下:
omp_set_dynamic(1);
omp_set_num_threads(12);
#pragma omp parallel