我正在对二维数组进行热力学模拟。阵列为1024x1024。 while循环迭代指定的时间,或者直到goodTempChange为false为止。根据块的温度变化大于定义的EPSILON值,将goodTempChange设置为true或false。如果阵列中的每个块均低于该值,则板处于静止状态。该程序可以正常工作,我的代码没有问题,我的问题是串行代码绝对使openmp代码无所适从。我不知道为什么我尝试删除所有内容,但平均值计算只是您想要的正方形周围上下左右四个块的平均值,而它仍被串行代码破坏。我以前从未做过openmp,并且我在网上查找了一些东西来做自己拥有的事情。我没有发现任何竞争条件,因此以最有效的方式将关键区域中的变量包含在内。我真的看不出有什么问题。任何帮助将不胜感激。谢谢。

while(iterationCounter < DESIRED_ITERATIONS && goodTempChange) {
  goodTempChange = false;
  if((iterationCounter % 1000 == 0) && (iterationCounter != 0)) {
    cout << "Iteration Count      Highest Change    Center Plate Temperature" << endl;
    cout << "-----------------------------------------------------------" << endl;
    cout << iterationCounter << "               "
         << highestChange << "            " << newTemperature[MID][MID] << endl;
    cout << endl;
  }

  highestChange = 0;

  if(iterationCounter != 0)
    memcpy(oldTemperature, newTemperature, sizeof(oldTemperature));

  for(int i = 1; i < MAX-1; i++) {
  #pragma omp parallel for schedule(static)
    for(int j = 1; j < MAX-1; j++) {
      bool tempGoodChange = false;
      double tempHighestChange = 0;
      newTemperature[i][j] = (oldTemperature[i-1][j] + oldTemperature[i+1][j] +
                              oldTemperature[i][j-1] + oldTemperature[i][j+1]) / 4;

      if((iterationCounter + 1) % 1000 == 0) {
        if(abs(oldTemperature[i][j] - newTemperature[i][j]) > highestChange)
          tempHighestChange = abs(oldTemperature[i][j] - newTemperature[i][j]);
        if(tempHighestChange > highestChange) {
          #pragma omp critical
          {
            if(tempHighestChange > highestChange)
              highestChange = tempHighestChange;
          }
        }
      }
      if(abs(oldTemperature[i][j] - newTemperature[i][j]) > EPSILON
         && !tempGoodChange)
        tempGoodChange = true;

      if(tempGoodChange && !goodTempChange) {
        #pragma omp critical
        {
          if(tempGoodChange && !goodTempChane)
            goodTempChange = true;
        }
      }
    }
  }
  iterationCounter++;
}

最佳答案

试图摆脱这些关键部分可能会有所帮助。例如:

#pragma omp critical
{
  if(tempHighestChange > highestChange)
  {
    highestChange = tempHighestChange;
  }
}

在这里,您可以将每个线程计算出的highestChange存储在局部变量中,并在并行部分结束时获取所拥有的highestChange的最大值。

10-07 19:29
查看更多