【问题标题】:Does the compiler optimize in this case?在这种情况下编译器会优化吗?
【发布时间】:2017-08-22 15:56:27
【问题描述】:

我正在使用 Visual Studio,目前正在用 C++ 创建一个游戏引擎,它是 2D 的。目的是学习现代游戏引擎架构和一般的基于组件的系统。这意味着我有一个非常注重性能的心态(即使在现代硬件上为 2D 开发时性能并不是什么大问题)。

编译器会优化这样的东西吗?

template<class T>
inline T & Scene::accessComponent(unsigned int id)
{
    if (dynamic_cast(T*) < Transform > ) {
        ...
    }
    else if (dynamic_cast(T*) < Collidable > ) {
        ...
    }
    else if (dynamic_cast(T*) < AnotherComponentType > ) {
        ...
    }

    etc ...
}

我听说如果一个函数在顺序调用中进入相同的逻辑门,编译器可以针对未来的调用进行优化。这也适用于模板化函数吗?如果 T 在顺序调用中属于同一类型,编译器会优化吗?

我无法分析任何内容,因为目前代码很混乱,引擎中允许访问组件调用的不同部分尚未实现。所以我有点在计划阶段。

【问题讨论】:

  • 你在描述分支预测,是一些计算机架构的特性,独立c++。
  • 在运行时,模板函数实例与非模板函数相同。
  • 把代码放到godbolt.org,自己看看。虽然你真的不应该为 ECS 做任何演员表。
  • @nwp 我之所以使用所描述的方法是因为开发人员无论如何都需要使用强制转换来访问特定组件之一,即可编写脚本。这些是由开发人员定义的,因此引擎不知道派生类型是什么。因此,开发人员只使用一个通用函数来访问所有组件会更有意义。
  • 您可以制作 ECS,而无需让组件从基类继承,也无需强制转换,这对开发人员来说更容易,产生更简洁的代码,甚至可能为您提供更好的性能,因为您不需要需要dynamic_casts.

标签: c++ game-engine compiler-optimization


【解决方案1】:

这段代码肯定不应该在面向性能的代码中完成。它有多个分支。从逻辑上讲,每次进行 dynamic_cast 检查时至少有两个分支:一个由编译器自身生成的分支(用于检查 RTTI)和一个由您的 if 语句生成的分支。

现代硬件中的分支预测器功能强大但有限。至少,它们的数量是有限的,如果事件的分布或多或少是均匀的,它们就会失败。

即使分支预测成功,您仍然会在分支计算本身上失去一些循环。

我完全看不出动态演员的理由。由于您的类已经是多态的,只需调用相应的虚拟方法即可。

【讨论】:

  • 谢谢!我会接受这个。不过,我没有多态类(可编写脚本除外),因此它可能不算作 ECS。原因是除了更新之外我没有发现任何常见的行为,但这取决于组件类型需要不同的参数。
猜你喜欢
  • 1970-01-01
  • 2011-10-30
  • 2017-08-01
  • 1970-01-01
  • 2020-01-02
  • 2017-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多