Почему мое моделирование C ++ N-тела имеет пульсирующее замедление производительности?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Почему мое моделирование C ++ N-тела имеет пульсирующее замедление производительности?

Сообщение Anonymous »

Я разрабатывал 2D-моделирование гравитации N-Body в C ++, и я столкнулся с интересной проблемой производительности. Вместо стабильной частоты кадров время обновления приложения систематически пульсирует между «быстрым состоянием» и «медленным состоянием». Проблема возникает с помощью std :: execution :: par_unseq и, что удивительно, также с помощью std :: execution :: seq .
Проблема производительности
Основная проблема - цикклическое замедление. Функция App :: Update < /code>, которая почти полностью является расчетом N-тела, демонстрирует два различных режима производительности: < /p>

«Быстрое состояние» со средним временем обновления ~ 60 мс. < /Li>
«Медленное состояние» со средним временем обновления между 90-150 мс. 70% своего времени в этом «медленном состоянии», что приводит к плохой общей частоте кадров. The following performance analysis graph clearly shows this bimodal distribution over time:
Изображение

The Core Calculation Code
Here is the simplified, core logic from Cpuacceleratorpar.cpp , который выполняет расчет N-тел. Тела хранятся в std :: vector , где Body является простой структурой позиции, скорости и массовых векторов.void CpuAcceleratorPar::Update(std::vector& bodies, double dt)
{
const std::size_t n = bodies.size();
if (n == 0)
return;

std::vector idx(n);
std::ranges::iota(idx, std::size_t{ 0 });

// Pass 1: compute accelerations
std::vector acc(n, Vector2{});
std::for_each(std::execution::par_unseq, idx.begin(), idx.end(), [&](std::size_t i) {
Vector2 ai{};
const auto pi = bodies.Position;

for (std::size_t j = 0; j < n; ++j)
{
if (j == i) continue;

const Vector2 r = bodies[j].Position - pi;
const double dist2 = r.LengthSquared() + 1e-10; // softening2
const double inv = 1.0 / std::sqrt(dist2);
const double inv3 = inv * inv * inv;

ai += r * (6.67430e-11 * bodies[j].Mass * inv3);
}
acc = ai;
});

// Pass 2: Integrate
std::for_each(std::execution::par_unseq, idx.begin(), idx.end(), [&](std::size_t i) {
bodies.Velocity += acc * dt;
bodies.Position += bodies.Velocity * dt;
});
}
< /code>
Что я попробовал < /h2>

Быстрый обратный квадратный корень: я думал, что это может быть денормализованная проблема
с 1.0 /std :: sqrt (dist2) < /code>. Я попробовал быстрое обратное приближение к квадрату корня
, но это не имеет значения. Замедление
не сама функция sqrt. Пульсация все еще была там, в целом
медленнее. Это означает, что проблема является фундаментальной для самого расчета
. Спасибо! 😄

Подробнее здесь: https://stackoverflow.com/questions/797 ... e-slowdown
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»