【发布时间】:2017-11-29 21:30:46
【问题描述】:
我正在尝试在 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);
}
}
这是 calculateAstoidMov 是:
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;
}
我应该如何并行化计算力的循环? 我希望它很清楚......
【问题讨论】:
-
forces的单个实例被所有线程共享,可以被多个线程写入。 -
@1201ProgramAlarm ,但问题是该行是所有逻辑所在的地方。如果我在线程访问该变量时加锁,则根本不会有有用的并行化
标签: c++ multithreading parallel-processing openmp