前言

  在开发RBF节点的过程,我进行了性能测试。
  当RBF节点的使用数量达到100个以上之后,maya窗口的帧速率就已经掉到个位数。
  而这个还是没有添加任何额外绑定系统的情况。
  张峥前辈担心后续搭建出来的表情系统会过于臃肿,导致动画制作很麻烦。
  因此将性能优化提升到首位。
  于是我就尝试了使用 Maya 的 C++ 多核操作来提升运算效率。


原本的RBF节点运行效果

origin

多核运算的RBF节点

多核

  最终实现的效果是令人失望的,CPU占用率上去了,然而整体的运行效率却更低了。

Maya C++ 多核方案

  在官方文档中,maya的多核操作有很多种方法。

  • OpenMP
  • Intel TBB
  • Maya API

  OpenMP 使用起来惊人地简单,但是效率提升不明显,因此我并没有测试。

多核

  Intel TBB 我拿来测试了,但是效果不太理想。
  Intel TBB 没有python多线程的 join 方法,因此它实现的多线程是异步而无法同步的。
  这样的输出结果无法将多个运算结果的汇总到一起。
  尽管这种问题是可以用代码来弥补的,不过 Maya API其实已经封装好了。
  因此最后我采用了 Maya API 的线程池来实现功能。

多核

  关于如何使用 Maya API 的线程池,官方只给了命令相关的例子,没有变形器的例子,变形器使用 TBB 实现的。
  因此我在 github 上找到几个通过 maya 线程池实现多核功能的变形器源码。

Maya API 多核性能测试

  多核运算最重要的步骤是对运算过程的切分。
  我看到maya给出的测试例子,包括网上实现的多核,都是对模型大量面数处理的时候使用的。
  也就是说有一个数量级很大的for循环,而for循环的结果是不需要同步处理的情况。
  不过放到 RBF 节点中,这种情况显然不太合适。
  RBF 是大量短小精悍的 for 共同运算的结果,因此我也不太清楚如何正确切分这个运算过程。

多核

  我最后是将RBF运算的一些双重for循环替换为 多核切分来提神效率。
  因此我的多核切分就会很琐碎,重点是开多线程处理也是有系统开销的。
  因此如果我把线程切分的非常碎的话,就会开非常多的线程,最后CPU占用率可以达到70%-80%。
  然而大量的CPU运算都浪费在线程的处理上了,反而拖慢了运算的效率,得不偿失。

  所以最后的结果时Maya多核的CPU占用率上去了,但是运行效率还不如单核的理想(:зゝ∠)
  另外我找到的变形器中 MayaNodes 就是专门针对Maya多核性能测试而开发的。
  开发者给出的结论非常让人沮丧。

多核

  或许正是maya多核上的劣势才导致了 Ziva 这些模拟软件的运行卡顿吧。

附注

  上面动图演示有极高的CPU占用率,是因为我将任务切分数调的很高。(我设置了100)
  由于开线程是有系统开销的,虽然这个过程是由TBB内部处理的,但是任务切分越多,开销肯定是越大的。
  因此maya的官方说明也提到,这个开销需要自己把握,拿捏尺度。
  我这里设置的任务切分数显然是过分了。

  不过即便将任务切分调成2。
  CPU占用率不仅没上去,而且效率还是不如单线程的。
  因此github上的测试或许是对的,maya的多核运算本质还是单线程的,效率提不起来。