并行处理冲突对
Parallel Processing Collision Pairs
我正在编写一些用于并行处理碰撞的代码,预期的结果是每个线程都有一个加速,但我在数据处理上没有得到任何加速,因为我在parallel_reduce()
里面有一个关键部分,我相信它序列化了太多对对象的访问。代码的外观如下:
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);
有没有办法通过并行或访问的序列化太多来获得更高的速度?
观察:
- bodyA() 和 bodyB() 是在 bodyContact 容器中重复多次的对象。
- 目前
parallel_reduce()
只做一个乘法(关键部分),但会变得更加复杂。
double parallel_reduce(){
#pragma omp critical
this->vel_ *= 0.99;
return vel_.length();
}
实际时间:
- 序列号, 25.635
- 并行,123.559
使用 OpenMP 构造总是有成本的,因此请避免在循环中使用并行,在实现之后,它可以在每次新线程启动时启动,而不是重新唤醒以前启动的线程。
事实上,如果 bodyContact.size() 很小,而 do {} 在步数上很大,而且parallel_reduce非常快,那么仅仅用几个 OpenMP 编译指示就很难实现可扩展性。
#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);
}
以上可能不仅速度较慢,而且很可能是错误的; 所有线程都在尝试更新相同的 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
。
相关文章:
- OpenCV特征匹配并行处理
- 这是并行处理多个作业而不阻塞主线程的合适方法
- 尝试与 OpenMP 并行处理链表数据
- GPU与并行处理CPU
- 为什么在某些特定情况下具有多个线程(并行处理)会降低性能
- 接收不一致的访问冲突,处理队列
- C 最常见的并行处理方法.pthreads
- 并行处理冲突对
- openCV用CUDA-并行处理
- 如何正确选择rng种子进行并行处理
- 什么样的数据结构可以实现并行处理
- 并行处理库
- 是否可以在Intel Xeon Phi上使用std::thread进行并行处理
- 划分4D笛卡尔网格进行并行处理
- 并行处理数组索引的最佳方式
- c++期货并行处理
- c++for_each并行处理两个容器
- OpenMP对带有映射的循环进行并行处理
- 如何使用 c++ 逐行并行处理
- c++算法循环并行处理