问题
最近遇到联合编译器,编译 C++ 代码突然变得很慢,需要 10 分钟+
于是进行了一番排查,记录一二
1. 确认联合编译器服务是否正常、并升级
查看编译记录,似乎联合编译器不怎么正常了,大多数均在本地打包机上编译 C++ 代码
最开始以为,联合编译器坏掉了,因此重新安装升级了联合编译器,结果还是一样
2. 更改联合编译器调度算法为 round robin
修改调度算法后,可以确认联合编译器是正常工作的,每个从机都有 C++ 在编译
但是结果还是很慢,没大的变化
3. 写磁盘遇到瓶颈?
于是猜测,是否哪里遇到瓶颈
首先想到的是联合编译器的工作原理:
- CPP 文件要通过调度器分发到从机
- 从机的 .o 文件需要通过调度器所在主机,再到目标机
.o 文件会涉及到写调度器所在主机磁盘以及目标机磁盘
而磁盘读写速率是有限的
于是观察了下,对应主机的磁盘读写、网络上下行速率
但均在两、三分钟恢复空闲
4. 发现单 cc1plus 进程 100% CPU 跑 6 、7 分钟
在观察每台从机 cc1plus 进程情况时,发现都很多
但很快都没了,但是会某从机一个 cc1plus 进程会一直 100% 持续 6 、7 分钟
于是看了下该进程的命令行,确定在编译,但是命令行的编译文件,已经被联合编译器重名为 uuid 型文件名了
5. 单核编译程序,查看每个 CPP 编译花费时间
CMakeLists.txt 加:
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CMAKE_COMMAND} -E time")
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CMAKE_COMMAND} -E time")
可以打印编译、链接时间
于是发现一 CPP 文件需要花费 6 、7 分钟
至此发现了慢的原因
木桶效应
通常性能优化时,经常考虑单点、热点问题
今天在联合编译器使用上,也发现单点问题
其他 CPP 文件很快编译完成,但是卡在 1 个非常慢速的 CPP 文件编译上,导致整体时间被拖垮
联合编译器极限时间耗时
之前使用联合编译器,从没认真思考过,想当然认为机器越多编译速度越快
现在总结下,联合编译器,至少耗时,受以下因素影响:
- A. MAX(单个 CPP 编译时间)
- B. .o 文件数量的 2 次写磁盘时间
- C. .o 文件数量的 link 时间
至少需要花费:
MAX(A, B) + C
其中, B C 与文件数量成正比
消除单 CPP 编译时间
- 根本消除,可通过把单 CPP 文件内容,拆分打散 10 份,这样可以充分利用联合编译器分布式编译
- 非 Release 版尽量保留缓存,贴近增量编译(指标不治本)
以上