Почему мое моделирование 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[i].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[i] = ai;
    });
    
    // Pass 2: Integrate
    std::for_each(std::execution::par_unseq, idx.begin(), idx.end(), [&](std::size_t i) {
    bodies[i].Velocity += acc[i] * dt;
    bodies[i].Position += bodies[i].Velocity * dt;
    });
    }
    < /code>
     Что я попробовал < /h2>
    
      Быстрый обратный квадратный корень: я думал, что это может быть денормализованная проблема
    с 1.0 /std :: sqrt (dist2) < /code>. Я попробовал быстрое обратное приближение к квадрату корня
    , но это не имеет значения. Замедление
    не сама функция sqrt. Пульсация все еще была там, в целом
    медленнее. Это означает, что проблема является фундаментальной для самого расчета
    . 
    
    [/list]
    Что может вызвать? к нагрузке из петли рендеринга [b] [/b]. The graph below shows the performance with rendering disabled:
    [img]https://i.sstatic.net/MB3mwwHp.png[/img]
    
    
    [b]System Specifications[/b]
    [list]
    [*] [b] CPU: [/b] Intel Core I3-8130U (2 ядра, 4 потока @ 2,20GHZ)
    [*] [b] Graphics: [/b] Intelt intel UHD Graphics 620
    [*] [b] build> strong> Follow uhd Flags/o Flads/O2 
    
    Подробнее здесь: [url]https://stackoverflow.com/questions/79781845/why-does-my-c-n-body-simulation-have-a-pulsating-performance-slowdown[/url]
Ответить

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

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

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

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

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