Yadcc
是一套腾讯广告自研的工业级C++分布式编译系统。目前在我们1700+核的集群中每天编译300,0000+个目标文件,产出约3~5TB,已经持续稳定运营 8 个月。
2021 年 6 月,正式对外开源。
取决于代码逻辑及本地机器配置,yadcc
可以利用几百乃至1000+核同时编译(内部而言我们使用512并发编译),大大加快构建速度。
具体简介及技术细节可以参考我们的技术文档。
yadcc
需要 GCC 8 及以上版本的编译器,基于yadcc
进行分布式编译时可以支持其他更低版本编译器。ln -sf yadcc g++
创建的符号链接)PATH
头部,这样构建系统就会实际执行yadcc
来编译yadcc
会按照命令行对源代码进行预处理,得到一个自包含的的预处理结果由于预处理时间通常远小于编译时间,因此这样可以降低单个文件的本地开销。同时,由于等待编译结果时本地无需进行操作,因此可以增大本地的编译并发度(如8核机器通常可以make -j100
),以此实现更高的吞吐。
需要注意的是,分布式编译通常只能提高吞吐,但是不能降低单个文件的编译耗时(假设不命中缓存)。因此,对于无法并发编译的工程,除非命中缓存,否则分布式编译通常不能加快编译,反而可能有负面效果。
我们的系统由调度器、缓存服务器、守护进程及客户端组成:
同时,我们做了多层重试,确保不会因为网络抖动、编译机异常离线等工业场景常见的问题导致的不必要的失败。
Yadcc
自带了必要的第三方库,因此通常不需要额外安装依赖。
需要注意的是,yadcc
通过git-submodule引用flare
,因此编译之前需要执行git submodule update
拉取flare
。另外由于flare代码仓库需要git-lfs支持,因此您还需要安装git-lfs。具体可以参考flare
的相关说明:
git clone https://github.com/Tencent/yadcc --recurse-submodules
或
git clone https://github.com/Tencent/yadcc
cd yadcc
git submodule init
git submodule update .
yadcc
可以使用如下命令编译yadcc
:
./blade build yadcc/...
搭建环境及使用方式可以参考详细文档。
我们搭建了一个 1000 多核的测试机群,在一些大型 C++ 项目上实测了效果。
LLVM 项目:
在我们的测试环境中共计 6124 个编译目标,结果如下:
对于我们内部的一组更大的实际产品项目代码上:
详情参见性能测试对比。
总体而言,yadcc
有相当明显的性能优势。
对于大型 C++ 项目,构建速度一直是个比较棘手的问题,因此目前也已经有了一些相关的项目:
比较而言,Bazel 相关的两个协议是非跨构建系统的,只能用于 Bazel 或者支持这些协议的构建系统;distcc 缺乏统一的调度;其他几个只是编译缓存;icecream 是和 yadcc 最接近的,也是我们一开始尝试使用的,不过在并行数百个任务时,性能和稳定性表现不佳。
因此我们开发了 yadcc,除了提供更好的性能和可靠性外,还额外增加了一些其他功能。