c++缩短编译时间作用大吗?
- 1 个点赞 👍
这就显示出来增量编译有多重要,另外可以用ccache加速
查看全文>>
L1AHvAn13 - 789 个点赞 👍
2016 年的时候,华为固网某个部门,编译一个有 500w 行源码的工程要 3 个多小时。后来,有个员工重写了大量 makefile 文件,改成分布式编译,编译时间缩短到 30 分钟。
部门给了 A 绩效。公司给了金牌个人。
组里面有个曾经和他一起共事的同事说,要是没有优化编译时间这回事,他合同到期应该不会续签,在此之前连 B+都很少拿。
没想到随手一答,居然那么多同行围观。再补充一点细节。
编译优化这事对于效率提升是巨大的。但风险也是极高的,很多人诟病编译太慢,但都不敢去优化。在华为干这个事,要抱着破釜沉舟的心态去搞。就像上面说的那个人,反正大概率也不续签了,搞出问题离职就行。
按照华为开发的要求,只要被代码修改影响的在研产品都需要有严格的验证。比如,库上代码被代码分析工具扫描出来指针delete后没有赋值nullptr。你在后面加上一句 ptr = nullptr。那么工作量就来了,所有使用了这个函数的在研项目你都得验证有没有问题。
回到编译优化问题,在华为搞这事的影响非常大,搞成功后的结果可能会很微小(就像评论区说的,公司没有任何奖励)。但是工作量非常大,验证的产品非常多。好在,成果是好的,把时间缩短到了原来的六分之一。
再补充一个小故事。
那时候我还是一个萌新,编译时间还是要3个多小时。某天下午5点的时候,主管发消息给我。
主管:晚上加个班,版本验证了再走。
我:好的。
等到了晚上8点30。
我:x哥,版本什么时候可以用?
主管:再等等,刚才有个傻逼紧急合入,重新跑构建了。
我:好的。
等到了晚上10点30。
我:x哥,版本出来了没有?
主管:再等等,编译出错,代码回退了,正在跑构建。
等到晚上12点。
我:x哥,版本可以用了吧?
主管:再等等,今晚上一定有版本可以用。
等到凌晨1点20。
主管:邦彦,你早点回去休息吧,版本出不来了。
我。。。。。。
编辑于 2023-06-29 09:51・IP 属地四川查看全文>>
邦彦 - 196 个点赞 👍
会的。大型项目编译几小时也不少见。
如果几小时能缩短的10~20分钟。开发体验会得到大幅度改善。
中项目,如果10~20分钟能缩短到1~2分钟,开发体验也会得到大幅度改善。
小项目,如果5分钟能缩短到30秒以内,开发体验也会得到大幅度改善。
我们的项目以前要编译1~2小时,现在基本给优化到几分钟了。整体体验很好。
其实对于这个,我个人的推荐是:C++程序尽量规划为多进程架构,不要将整个项目放进一个可执行文件,哪怕作为动态库也不太行。因为大型项目有相当多的时间会耗费在链接这个环节。
而链接这个环节,无法用ccache加速,无法并行,无法分布式编译。。。可以说是几乎没有任何手段缩短。
那么我们怎么做呢?把大项目分成20个小项目。分成几十个独立的可执行文件。独立的可执行文件之间用进程间通讯。有效的提升了模块化以及降低了耦合,分工与调试都变得更简单清晰。而且更重要的,大幅度提升了编译速度(其实是提升了链接速度)。
我猜,随着文件尺寸的增长,链接时间,大约是指数级别增长吧。
发布于 2023-06-29 09:49・IP 属地湖北查看全文>>
pansz - 83 个点赞 👍
上班等编译的时间顺手回答下,可以说是相当切题了..
TL;DR
相当重要。
先说说我的体会,再谈一些以前看到的趣闻。
六月初刚入职一个做存储产品的部门,几万行C++,再加上相关的库等等,规模也不算小了,一次完整编译,40~60分钟不等(O0 debug模式)。
刚来的那一周一直在看代码、gdb追踪,除了最开始build了一次(为了方便调试没开优化,debug模式,没有那么多编译、链接期优化)基本不用编译代码,因此无甚感受。
后面开始写gtest、写功能的时候就开始难受了...
不是在黑我司,跟同事前辈聊他们也说这两年代码也在拆了,你看我们那两个两万多行的Server和Servertest就是分拆之后的了
分拆之后的了
之后的了
的了
。。。
他们说的没错,我能看出来很多component现在是单独自己的文件、测试,但架不住核心模块很多还是缠在一起,变成些个巨无霸的.cc文件,这就直接导致:
- compile时单个文件过大,大到编译它本身花的时间成为lock step中最长的,linker就在那等它编译完,它是显著的bottleneck
- link时这个文件对外部的引用过多,又是没法并行化,导致link time解析符号表、重定位的时间巨长
粗略估计了下,只修改这单个巨无霸文件引发一次重编译、链接的时长大约在20分钟左右,其中1/4~1/3的时间是编译,剩下大头是链接。
我思考过这是不是我电脑太烂了,16英寸mbp 2019,i7-9750H,只有6个物理核。但后来我想了想也不是,或者不完全是。
我这个增量编译的场景压根儿不吃核心的,当然确实吃主频,可cpu主频也没办法scale up得上你代码膨胀的速度啊...
所以这确实是一个问题,而且是一个相当大的问题。我很久以前曾刷到 介绍ReScript解决的痛点:
...
Scalability主要体现在编译性能上,我们可以在100ms左右增量编译一个10,000文件的大型项目,这点很符合大公司的胃口,因为大公司的代码库很大,编译性能严重影响程序员的生产力。当时还很纳闷儿,有这么夸张吗?现在我明白了,操,什么吕布骑狗。。。
实际写代码,我自己有一些治标不治本的方法或许可能提供给各位参考(为了构建得快一点,我特么真的想了很多... 而这时候熟悉构建系统就很重要了),以cmake为例
- 把不相干的target暂时注释掉,确保只构建你要测试的target
- 把优化暂时关了,一方面单文件编译优化,另一方面C++是有很多链接期优化的,这些在规模大的时候也非常耗时
- 如果功能非常独立(不依赖整个系统),可以暂时开一个单独的target,只build这一个小target,等测试得差不多了再把它加到主干target上测试
- 多clone几个仓库,编译一个的时候在其他仓库上改其他分支...
最后附上一个趣闻(不是在黑rust,我也很喜欢rust,但这真的很难绷2333):据说,TiKV 一天只有 24 次编译机会,用一次少一次
...
TiDB 中的其他节点是用 Go 编写的,当然,Go 与 Rust 有不同的优点和缺点。PingCAP 的一些 Go 开发人员对于不得不等待 Rust 组件的构建而表示不满。因为他们习惯于快速的构建-测试迭代。
在 Go 开发人员忙碌工作的同时,Rust 开发人员却在编译时间休息(喝咖啡、喝茶、抽烟,或者诉苦)。Rust 开发人员有多余的时间来跨越内心的“阴影(译注:据说,TiKV 一天只有 24 次编译机会,用一次少一次)。光度8663 次赞同去咨询编辑于 2023-06-29 22:25・IP 属地上海真诚赞赏,手留余香还没有人赞赏,快来当第一个赞赏的人吧!查看全文>>
光度 - 60 个点赞 👍
啊哈哈~
你可以尝试着编译一下 Chrome,相信你会对这个问题有全新的认识~
而 Chrome 也只是桌面端的中大型项目,一些巨型企业级服务软件的编译时间会更长,如果一些关键步骤搞错了,还得重新来过哟~
发布于 2023-06-28 16:10・IP 属地北京查看全文>>
快乐代码 - 14 个点赞 👍
查看全文>>
彭八百