• RuntimesUnity
  • MeshGenerator.cs里的ScaleVertexData函数的性能问题

为什么MeshGenerator.cs里的ScaleVertexData函数

为什么vbi[i] *= scale; // vbi[i].x *= scale; vbi[i].y *= scale;要注释掉后边的算法呢?实测了一下,使用注释的算法性能更好一些

Related Discussions
...

MeshGenerator.cs中的ScaleVertexData函数中,注释掉vbi[i].x *= scale; vbi[i].y *= scale;并直接使用vbi[i] *= scale;的原因可能是为了简化代码和提高性能。以下是代码的具体实现:

public void ScaleVertexData (float scale) {
    var vbi = vertexBuffer.Items;
    for (int i = 0, n = vertexBuffer.Count; i < n; i++) {
        vbi[i] *= scale; // vbi[i].x *= scale; vbi[i].y *= scale;
    }

    meshBoundsMin *= scale;
    meshBoundsMax *= scale;
    meshBoundsThickness *= scale;
}

在这个函数中,vbi[i] *= scale;直接对整个向量进行缩放,而不是分别对xy分量进行缩放。这种做法的好处是:

  1. 简化代码:直接对向量进行缩放比分别对每个分量进行缩放更简洁。
  2. 提高性能:在某些情况下,直接对向量进行缩放可能会比分别对每个分量进行缩放更高效,因为它减少了循环体内的操作次数。

然而,具体的性能提升可能取决于编译器的优化和具体的硬件架构。在你的实测中,使用注释掉的办法(即分别对xy分量进行缩放)性能更好,可能是因为在你的特定环境下,这种方式更符合编译器的优化路径或硬件的执行效率。

如果你发现注释掉的办法性能更好,可以继续使用这种方式,但需要确保在所有情况下都能正确处理数据。

    Spinebot 在mono环境和il2cpp环境下都是使用vbi[i].x *= scale; vbi[i].y *= scale;的算法性能更好

    修改前:

    修改后:

    这是我用android真机测试的结果

    @chongshengzhujue This looks very much as if the profiler is introducing the overhead, not the actual code. You need to disable Deep Profiling and similar features, otherwise single otherwise inlined (math) function calls end up introducing a lot of overhead.

    Could you measure any difference with DeepProfiling disabled?

      Harald
      感谢您的回复

      我使用的unity编辑器版本是2019.4.40,这个版本的Vector3的(operator *)还不是inline函数

      但是在unity 2020.3.38版本的(operator *)已经是inline函数了

      我用以下方式分别对2019.4.40和2020.3.38版本进行了测试
      测试环境:
      Android
      il2cpp

      没有使用Deep profiling或者development模式

      2019.4.40
      代码1的执行时间是7.79ms
      代码2的执行时间是1.96ms

      2020.3.38
      代码1的执行时间是1.75ms
      代码2的执行时间是2.77ms

      在2020.3.38版本使用 vbi[i] *= scale 表现更好

      @chongshengzhujue Oh dear, this was indeed unexpected! Thanks for profiling and for sharing your findings!

      I just read the following Unity forum thread which confirms your findings:
      https://forum.unity.com/threads/vector3-and-other-structs-optimization-of-operators.477338/

      I was somewhat shocked to see that the (C++) compiler did not inline and discard the unnecessary statements accordingly. It might still be worth a try whether setting the Project Settings - Player Setting C++ Compiler Configuration from Release to Master improves the issue, which should allow optimizations at the linker stage. In case you haven't used this setting yet, you might want to give it a go and see if things improve. theoretically it should improve especially on Unity 2019.4.40 prior to the *= operator inlining (where the link-time optimizations should then discard the superfluous statements accordingly).

      It's at least good to read that since later versions of Unity 2020.3 this seems to have been addressed accordingly. We will add some #if code-branches to address this accordingly on older Unity versions.

      Thanks for reporting and taking the additional time to profile everything!