Я разрабатывал 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 является простой структурой позиции, скорости и массовых векторов.
Я разрабатывал 2D-моделирование гравитации N-Body в C ++, и я столкнулся с интересной проблемой производительности. Вместо стабильной частоты кадров время обновления приложения систематически пульсирует между «быстрым состоянием» и «медленным состоянием». Проблема возникает с помощью std :: execution :: par_unseq и, что удивительно, также с помощью std :: execution :: seq . Проблема производительности Основная проблема - цикклическое замедление. Функция App :: Update < /code>, которая почти полностью является расчетом N-тела, демонстрирует два различных режима производительности: < /p> [list] [*] «Быстрое состояние» со средним временем обновления ~ 60 мс. < /Li> «Медленное состояние» со средним временем обновления между 90-150 мс. 70% своего времени в этом «медленном состоянии», что приводит к плохой общей частоте кадров. The following performance analysis graph clearly shows this bimodal distribution over time: [img]https://i.sstatic.net/isFbe2j8.png[/img]
The Core Calculation Code Here is the simplified, core logic from Cpuacceleratorpar.cpp , который выполняет расчет N-тел. Тела хранятся в std :: vector , где Body является простой структурой позиции, скорости и массовых векторов.[code]void CpuAcceleratorPar::Update(std::vector& bodies, double dt) { const std::size_t n = bodies.size(); if (n == 0) return;
Быстрый обратный квадратный корень: я думал, что это может быть денормализованная проблема с 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]