【问题标题】:Different answers when parallelize并行化时的不同答案
【发布时间】:2018-05-17 11:12:14
【问题描述】:
#pragma omp parallel for    
for (int i = 0; i <500; i++)
   for (j=i; j < 102342; j++)
    {
      Output[j] += staticConstant[i] * data[j-i];
    }
}

有些向量答案是相同的,有些是不同的。这可能是什么原因?起初我认为这可能是由于浮动,所以我将所有内容都转换为双精度数。会有 5-6 个答案相同或更大的块,随机值非常接近,而一些则相距甚远。

【问题讨论】:

    标签: c++ parallel-processing openmp


    【解决方案1】:

    您有多个线程写入Output[j]。这会导致竞争条件。一个线程写入的值被另一个具有不同值的线程替换。

    【讨论】:

      【解决方案2】:

      问题是你的内部循环有一个写竞争条件,因此,例如,以下两个语句可能并行发生:

      Output[42] = Output[42] + staticConstant[9] * data[42-9];
      Output[42] = Output[42] + staticConstant[19] * data[42-19];
      

      每一行的代码归结为:

      Load O[42] to R1
      Load C[] to R2
      Add R2 to R1
      Store R1 to O[42]
      

      但是,并行器可能会导致您的代码像这样运行:

      Load O[42] to R1
      Load O[42] to R3
      Load C[9] to R2
      Load C[19] to R4
      Add R2 to R1
      Add R4 to R3
      Store R1 to O[42]
      Store R3 to O[42]
      

      如您所见,Load O[42] 的两条线在添加 C[9]C[19] 之前加载了值,因此实际上忽略了第一个计算。

      最简单的解决方法是:

      for (int i = 0; i <500; i++)
      {
      #pragma omp parallel for    
         for (j=i; j < 102342; j++)
          {
            Output[j] += staticConstant[i] * data[j-i];
          }
      }
      

      现在只有内部循环被并行化,所以不会出现竞争条件。

      【讨论】:

      • 谢谢!
      • 另一种选择是交换两个循环。 j 循环有更多的迭代,所以并行化最外层的循环会导致更少的开销。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多