【发布时间】:2020-08-04 11:22:31
【问题描述】:
我正在尝试为自定义游戏引擎创建物理引擎。目前一切正常,但是当引擎必须处理大约 4000 个物理体时,我遇到了一些性能问题。我很确定这不是渲染引擎的错,因为它使用实例渲染来实现粒子效果(我目前正在测试的女巫),并且如果它们都是静态的,则可以处理大约 200K 粒子。
到目前为止,一旦所有的碰撞都得到解决,我会通过施加重力并以那里的速度平移物体来更新场景中的所有物理物体
函数如下所示:
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
}
这个函数将在每个物理体中运行一次,并像这样在 for 循环中调用
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::async 并且从函数返回的未来存储在物理引擎类的成员向量中,每次更新都会清除一次
使用我编写的时序代码,顺序循环耗时 0.00014 秒,多线程循环耗时 0.005 秒。我不希望多线程循环比顺序循环花费更长的时间,但它确实如此我假设我使用 std::async 错误或在错误的上下文中使用它。我正在运行的程序正在运行一个包含 300 个粒子的简单粒子模拟,所以还没有什么大不了的。
如果我使用 std::async 是否正确,请告诉我,因为我对多线程的概念还是很陌生,或者我是否使用了太多线程来降低引擎的性能,或者我是否应该使用计算着色器而不是多线程(如果使用计算着色器会提高引擎的性能,请留下一些链接以获取有关如何在现代 openGL 中使用 c++ 计算着色器的教程)
这两个函数都是物理引擎类的成员,SymplecticEuler() 函数是静态函数
谢谢
【问题讨论】:
-
你完成
fEulerFutures.reserve(all_bodys.size())了吗? -
如果您使用 gcc 9(或更高版本)或 MSVC,您可以尝试使用并行执行策略:
std::for_each(std::execution::par, all_bodys.begin(), all_bodys.end(), [](auto body) { SymplecticEuler(body); });
标签: c++ multithreading optimization compute-shader stdasync