循环C 的分割故障OpenMP
Segmentation fault Openmp in loop C++
我正在尝试在C 中并行化for循环。这个想法是给定小行星阵列,我计算了小行星之间产生的重力力。每个小行星都有其质量和位置。
我想并行化此循环,但是问题是当线程想要访问其他线程用于计算力的任何小行星时,存在分段故障。
这是我的代码:
//For each asteroid calculate forzes acting
for(unsigned long j=0; j<asteroids.size(); j++){
vector<double>forces(2);
{
#pragma omp parallel num_threads(4)
#pragma omp for
//I start in x instead of 0 to avoid redundance calculation
for(unsigned long x=j; x <asteroids.size(); x++){
//Avoid calculations on itself
if(asteroids[j].getX() != asteroids[x].getX() && asteroids[j].getY() != asteroids[x].getY()){
forces = asteroids[j].calculateAsteroidMov(asteroids[x], gravity, dmin);
}
asteroids[x].invertForze(forces[0], forces[1]);
}
}
for(unsigned long j=0; j<asteroids.size(); j++){
asteroids[j].updatePosition(t, width, height);
}
}
这是colculatostoidmov是:
std::vector<double> Asteroid::calculateAsteroidMov(Asteroid neighbour, double gravity, double dmin){
//Distance between
double xdist = x - neighbour.getX();
double ydist = y - neighbour.getY();
double dist = sqrt( xdist*xdist + ydist*ydist );
double xforze = 0;
double yforze = 0;
if(dist > dmin){
double slope = ydist / xdist;
if(slope > 1 || slope < -1){
slope -= trunc(slope);
}
double alfa = atan(slope);
xforze = ((gravity * mass * neighbour.getMass()) / (dist*dist));
yforze = ((gravity * mass * neighbour.getMass()) / (dist*dist));
if(xforze > 200){
xforze = 200;
}else if(yforze > 200){
yforze = 200;
}
xforze *= cos(alfa);
yforze *= sin(alfa);
sumxforze += xforze;
sumyforze += yforze;
}
std::vector<double> forces = {xforze, yforze};
return forces;
}
和updatePosition()
void Asteroid::updatePosition(double t, double width, double height){
//Spped update
vx += (sumxforze/mass) * t;
vy += (sumyforze/mass) * t;
//Position update
x += vx * t;
y += vy * t;
}
我应该如何平行计算力的循环?我希望这很清楚...
有两种解决此问题的方法。
1。双重缓冲:
维护两个小行星列表,一份是您从中读取的小行星,一份是您写的。许多线程可以安全地从同一个小行星中读取,并且您可以确保每个线程都写入其他人无法访问的内存区域。
对invertForze()
的作用,这也可能给您带来整个流程订单独立的好处。
2。模拟岛:
将您的小行星场分解为相互作用的小行星的子场,并以人均为基础,而不是以每asterotoid为基础。
这是大多数现代物理发动机使用的方法,因为它们使用这样的假设,即岛屿倾向于在框架之后保持相同的框架,但是与简单的双缓冲解决方案相比,放置要复杂得多。<<<<<<<<<<<<<</p>
问题是您同时从不同线程编写力向量。您可以将其声明移至内部循环,因此并发不会是问题。我还假设,当您不计算forces
时,您不应该致电invertForze
。
for(unsigned long j=0; j<asteroids.size(); j++){
{
#pragma omp parallel num_threads(4)
#pragma omp for
//I start in x instead of 0 to avoid redundance calculation
for(unsigned long x=j; x <asteroids.size(); x++){
//Avoid calculations on itself
if(asteroids[j].getX() != asteroids[x].getX() && asteroids[j].getY() != asteroids[x].getY()){
vector<double> forces = asteroids[j].calculateAsteroidMov(asteroids[x], gravity, dmin);
asteroids[x].invertForze(forces[0], forces[1]);
}
}
}
for(unsigned long j=0; j<asteroids.size(); j++){
asteroids[j].updatePosition(t, width, height);
}
}
相关文章:
- 分段故障(堆芯转储)矢量
- C++中的动态铸造故障
- 数组的指针从不分段故障
- OpenMP阵列性能较差
- vscode g++链路故障:体系结构x86_64的未定义符号
- 访问被拒绝后,c++中的故障保护代码
- OpenMP卸载说'fatal error: could not find accel/nvptx-none/mkoffload'
- 使用 GCC 卸载的 OpenMP 卸载失败,并出现"Ptx assembly aborted due to errors"
- Windows 10-使用gtkmm-3.0库和g++[包括再现]的分段故障
- OpenMP:并行更新数组总是需要减少数组吗
- 如何使用OpenMP并行这两个循环
- 从python调用openMP共享库时,未定义opnMP函数
- 如何使用OpenMP并行化此矩阵时间矢量运算
- 如何使用OpenMP使这个循环并行
- 如何通过替换顺序代码的while循环来添加OpenMP for循环
- 查找最近配对时的OpenMP竞赛条件
- 使用输入打破 OpenMP 中的循环
- 调试 CUDA MMU 故障
- 循环C 的分割故障OpenMP
- 使用openmp和分段故障并行K最近邻