Я пытаюсь создать физический движок для пользовательского игрового движка. На данный момент все работает нормально, однако у меня возникают некоторые проблемы с производительностью, когда двигатель должен иметь дело примерно с 4000 физическими телами. Я совершенно уверен, что это не ошибка движка рендеринга, поскольку он использует рендеринг экземпляров для эффектов частиц (ведь я сейчас тестирую) и может обрабатывать около 200К частиц, если они все статичны c.
до сих пор, как только все столкновения были разрешены, я обновляю все физические тела в сцене, применяя силу тяжести и переводя тела на их скорость
функция выглядит следующим образом:
void mint::physics::PhysicsEngine::SymplecticEuler(mint::physics::PhysicsBody* body)
{
mint::graphics::Entity *entity = body->GetEntity();
// -- Symplectic Euler
glm::vec2 gravity = glm::vec2(0.0f, (1.0f / core::Timer::Instance()->DeltaTime()) * 9.81f) * body->GravityScale();
glm::vec2 dv = (body->Force() * body->GetMassData()->inv_mass + gravity * core::Timer::Instance()->DeltaTime());
body->Velocity(body->Velocity() + dv);
glm::vec2 dxy = glm::vec2(body->Velocity() * core::Timer::Instance()->DeltaTime());
entity->Translate(glm::vec3(dxy, 0.0f));
// -- END -- Symplectic Euler
// -- update the collider
body->UpdateCollider();
// -- END -- update the collider
}
эта функция будет запускаться один раз для каждого физического тела и вызывается для l oop, например, так:
auto start = std::chrono::high_resolution_clock::now();
for (auto body : all_bodys)
{
//SymplecticEuler(body);
// -- using std::async
fEulerFutures.push_back(std::async(std::launch::async, SymplecticEuler, body));
//SymplecticEuler(body);
}
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<float> duration = end - start;
std::cout << "physics update took: " << duration.count() << std::endl;
Я использую std :: chrono, чтобы увидеть, как долго обновляется и у меня есть два разных способа реализовать это, один из них - просто вызвать SymplecticEuler(body)
, а другой - использовать std :: asyn c, и это будущее, возвращаемое функцией, сохраняется в векторе-члене Класс физического движка очищается один раз при каждом обновлении
с использованием написанного мною временного кода: l oop 0.00014 с, а многопоточность l oop - 0,005 с. Я бы не ожидал, что многопоточность l oop займет больше времени, чем последовательная l oop, но это так, я предполагаю, что я либо использую std :: asyn c неправильно, либо использую его в неправильном контексте. Программа, в которой я запускаю эту программу, запускает простую симуляцию частиц с 300 частицами, так что пока ничего большого.
Может кто-нибудь сообщить мне, правильно ли я использую std :: asyn c, потому что я все еще очень плохо знаком с концепцией многопоточности или использую слишком много потоков, чтобы снизить производительность движок или если мне следует использовать вычислительные шейдеры вместо многопоточности (если использование вычислительных шейдеров улучшило бы производительность движка, пожалуйста, оставьте несколько ссылок на руководства по использованию вычислительных шейдеров в современном openGL с c ++)
оба эти функции являются членами класса физического движка, а функция SymplecticEuler()
является функцией * c
Спасибо