并行处理碰撞对

时间:2012-11-14 01:54:32

标签: c++ parallel-processing openmp collision

我正在编写一些用于并行处理冲突的代码,预期的结果是为每个线程加速,但是我没有在数据处理上获得任何加速,因为我在{{1}内部有一个关键部分我相信它序列化了对对象的访问权限。这就是代码的外观:

parallel_reduce()

有没有办法通过使其并行或访问序列化过多来获得更快的速度?

观察:

  • bodyA() bodyB()是在bodyContact容器内重复自身的对象。
  • 目前do { totalVel = 0.; #pragma omp parallel for for (unsigned long i = 0; i < bodyContact.size(); i++) { totalVel += bodyContact.at(i).bodyA()->parallel_reduce(); totalVel += bodyContact.at(i).bodyB()->parallel_reduce(); } } while (totalVel >= 0.00001); 只进行一次乘法(关键部分),但会变得更复杂。
parallel_reduce()

实际时间:

  • serial,25.635
  • parallel,123.559

2 个答案:

答案 0 :(得分:1)

使用OpenMP结构总是有成本的,所以避免在循环中使用并行,遵循每次新线程时可以启动的实现,而不是重新启动先前启动的线程。

实际上,如果bodyContact.size()很小,而且步骤数量为do {}且并行,则parallel_reduce非常快,只需要几个OpenMP pragma就很难实现可扩展性。

#pragma omp parallel shared(totalVel) shared(bodyContact)
{
   do {
       totalVel = 0.;
       #pragma omp for reduce(+:totalVel)
       for (unsigned long i = 0; i < bodyContact.size(); i++) {
          totalVel += bodyContact.at(i).bodyA()->parallel_reduce();
          totalVel += bodyContact.at(i).bodyB()->parallel_reduce();
       }
   } while (totalVel >= 0.00001);
}

答案 1 :(得分:0)

上述情况不仅可能更慢,而且很可能是错误的;所有线程都试图更新相同的totalVel。吨竞争条件,但也有争用,缓存失效等等。

假设parallel_reduce()的东西没问题,你会喜欢更像

的东西
do {
    totalVel = 0.;
#pragma omp parallel for default(none) shared(bodyContact) reduction(+:totalVel)
    for (unsigned long i = 0; i < bodyContact.size(); i++) {
        totalVel += bodyContact.at(i).bodyA()->parallel_reduce();
        totalVel += bodyContact.at(i).bodyB()->parallel_reduce();
    }
} while (totalVel >= 0.00001);

将正确执行totalVel上的reduction