OpenMP に問題があります。並列ブロックで何かをインクリメントする場合、その式の前にアトミックを設定する必要があることを知っています。しかし、私のコードには理解できない部分があります。
ここでアトミックを使用する必要があるのはなぜですか?
#pragma omp parallel
{
double distance, magnitude, factor, r;
vector_t direction;
int i, j;
#pragma omp for
for (i = 0; i < n_body - 1; i++)
{
for (j = i + 1; j < n_body; j++)
{
r = SQR (bodies[i].position.x - bodies[j].position.x) + SQR (bodies[i].position.y - bodies[j].position.y);
// avoid numerical instabilities
if (r < EPSILON)
{
// this is not how nature works :-)
r += EPSILON;
}
distance = sqrt (r);
magnitude = (G * bodies[i].mass * bodies[j].mass) / (distance * distance);
factor = magnitude / distance;
direction.x = bodies[j].position.x - bodies[i].position.x;
direction.y = bodies[j].position.y - bodies[i].position.y;
// +force for body i
#pragma omp atomic
bodies[i].force.x += factor * direction.x;
#pragma omp atomic
bodies[i].force.y += factor * direction.y;
// -force for body j
#pragma omp atomic
bodies[j].force.x -= factor * direction.x;
#pragma omp atomic
bodies[j].force.y -= factor * direction.y;
}
}
}
そして、ここでそれを使用する必要がないのはなぜですか:
#pragma omp parallel
{
vector_t delta_v, delta_p;
int i;
#pragma omp for
for (i = 0; i < n_body; i++)
{
// calculate delta_v
delta_v.x = bodies[i].force.x / bodies[i].mass * dt;
delta_v.y = bodies[i].force.y / bodies[i].mass * dt;
// calculate delta_p
delta_p.x = (bodies[i].velocity.x + delta_v.x / 2.0) * dt;
delta_p.y = (bodies[i].velocity.y + delta_v.y / 2.0) * dt;
// update body velocity and position
bodies[i].velocity.x += delta_v.x;
bodies[i].velocity.y += delta_v.y;
bodies[i].position.x += delta_p.x;
bodies[i].position.y += delta_p.y;
// reset forces
bodies[i].force.x = bodies[i].force.y = 0.0;
if (bounce)
{
// bounce on boundaries (i.e. it's more like billard)
if ((bodies[i].position.x < -body_distance_factor) || (bodies[i].position.x > body_distance_factor))
bodies[i].velocity.x = -bodies[i].velocity.x;
if ((bodies[i].position.y < -body_distance_factor) || (bodies[i].position.y > body_distance_factor))
bodies[i].velocity.y = -bodies[i].velocity.y;
}
}
}
コードは現在でも機能していますが、その理由がわかりません。手伝って頂けますか?
敬具マイケル