APP下载

Unity开发元老抨击:C++20新功能造成编译缓慢与侦错建置效能低落

消息来源:baojiabao.com 作者: 发布时间:2024-05-15

报价宝综合消息Unity开发元老抨击:C++20新功能造成编译缓慢与侦错建置效能低落

负责Unity绘图引擎架构与发展的元老工程师Aras Pranckevičius,在个人部落格发表不看好C++ 20新功能Ranges的文章,而其在推特上的贴文也引来许多游戏开发工程师表达相同的感受。他提到,C++的编译时间与侦错建置(Debug Build)效能非常重要,但是C++ 20的新功能Ranges却让这两者都大幅增加。

11月ISO C++委员会在圣地亚哥召开了有史以来最大规模的会议,就C++ 20的语言更新草案进行讨论,而决议之一便是决定加入Ranges概念。Ranges是即将在C++ 20加入的新语法功能,Ranges用来帮助操作范围概念,能够让开发者简单的迭代具有开始和结束范围,并回传行为类似迭代器的物件。Ranges能够让语法更为简洁,使程式码阅读者不再需要自己解析复杂的for循环逻辑。

而主推Ranges和Concepts进入标准函式库的Eric Nieble,在自己的部落格发表标题为Standard Ranges的文章,然而却在Aras Pranckevičius发表评论之后,引来了部分游戏开发者的讨论,多数表达了反对意见。

 

Aras Pranckevičius使用目前最佳近似实作,由Eric Nieble撰写的range-v3,与简单版C++进行比较,他指出,C++ 20可能的问题至少有两个,编译时间与执行效能。他以Eric Nieble在自己部落格解释Ranges功能的毕氏三元数为例,以使用Ranges的C++编译程式码,编译时间长达2.92秒,比简单版C++的0.064秒还要多2.85秒,他表示,现代的CPU可以在3秒的时间,进行很大量的操作,像是以Clang在侦错模式中编译完整数据库引擎SQLite只要0.9秒,他质疑,编译毕氏三元数的5行程式码,却需要编译整个数据库引擎的3倍时间。

Aras Pranckevičius指出,编译时间是编译大型C++程式码库痛苦的来源,他随意列举Chromium、Clang/LLVM或UE4专案,都能让开发者轻易的体验这件事,他指出,编译时间就是一个C++待解决的大问题,而且应该在列表中排名之一,但是整个C++社群却假装这不是个问题。

由于在每个C++版本都会有更多的内容被放进标头档中,而且不像是C只在标头档案放入结构声明或是函式原型,C++会把整个模板化的类别和函式都加入。range-v3是一个大小1.8MB的程式标头档,而且即便预编译标头档,也只省下了0.7秒,整个编译时间仍然长达2.24秒,比简单版C++仍然长2.1秒。

另外,Aras Pranckevičius也提到,非最佳化建置效能也是非常重要的,在毕氏三元数的例子中,拥有Ranges的C++执行时间为300毫秒,而简单版的C++却只要2毫秒,也就是说执行效能慢了150倍,他认为,执行时间多2到3倍可以接受,慢10倍以上可能代表无法使用,而有Ranges的C++却是百倍以上。

执行效能对于游戏程式来说非常重要,Aras Pranckevičius表示,或许在部分应用侦错模式中慢10或100倍的时间,只是比较扰人,但是在游戏中,当每秒只有2个影格,则已经不是感觉上的问题,而是从根本上无法达到玩游戏的体验。即便建置最佳化后的执行效能与简单版本相同,但Aras Pranckevičius提到,要对最佳化的程式码侦错非常困难,这增加了工作难度。

相较之下,以C#实作毕氏三元数,使用Mono编译器编译需要0.2秒,而简单版的C#则是0.17秒,两者相去不远。Aras Pranckevičius认为,虽然C++ 20被称为现代C++,但事实上这些变化,并没有因为是“现代”而变得更好,大多数游戏开发人员都还停留在C++ 11、14或是17的版本,无论C++ 20增加了什么新功能,编译时间与侦错建置效能太差就毫无用武之地。

尽管Aras Pranckevičius的批评引起不少游戏开发者的声援赞同,但range设计目的是为了简化复杂的C++程式码,超多行数的大型程式码是否会如简单几行的毕氏三元数程式一样,遭遇到同样严重的效能问题,Aras Pranckevičius则没有进一步举例实测。

2019-01-03 13:33:00

相关文章