说起来可能有点反直觉,有时候不运行反而可以帮助我们加快速度,这正是网络浏览器运行的指导原则。不必在页面上加载所有内容,缓存的元素已经存在,不需要每次访问网站或网页时都重新加载。页面加载速度越快,浏览器的工作量就越少,最终结果也是一样的。
对于软件开发中的缓存,这一指导原则同样适用。在此情况下,缓存可以带来四点好处:
缓存可以分为多个等级,不同等级对性能的影响也不同。缓存粒度越细(例如,缓存整个代码库、缓存几行代码、缓存整个脚本的对比),性能就越好,降低的成本也就越多。
因此,在构思如何缓存构建工件时,能够缓存和复用最终工件(如可执行文件和库)固然不错,但您也应该考虑到更细粒度级。缓存还应包括中间工件,C++ 对象文件、调试信息以及构建的其他方面,如单元测试输出和自定义构建命令等。
缓存的一大驱动原理是:为了在编译期间成功复用缓存工件,当前任务必须具备与先前缓存的输出工件明确相关的输入依赖项。
为此,在任务中若要将工件存入缓存,该任务必须关联可以触发该缓存工件创建的所有输入依赖项。一般情况下,创建一个唯一的哈希 ID 来代表所有任务依赖项,包括输入文件、环境变量、命令行参数和其他输入等,就可以实现关联。该哈希 ID 将代表可以触发特定工件的所有依赖项。
只有当所有相关的输入依赖项都与原先执行任务对应的哈希值相同时,执行的任务才能复用先前缓存的工件。
目前常用的方法为了满足此要求,又给用户和我们想要缓存的工具/编译器带来了负担:
Incredibuild 的独特缓存构建法主要基于自身平台强大且经过实践验证的并行分发技术,注入进程的底层系统钩子(类似于反病毒软件的工作原理)。利用该技术,Incredibuild 可以自动映射读取到的每个文件或进程访问的其他输入,使其可供无缝使用和共享,以确定任务依赖关系,减轻用户负担和工具负担。
其工作原理如下:
这种利用系统钩子无缝跟踪进程依赖关系进行缓存的方法是一种全新的缓存方法(美国专利局认定此方法在技术上具有创新性,可以申请专利)。
让我们以 Visual Studio C++ 为例,来分析演示 Incredibuild 的工作原理,缓存将分为“方案级”、“项目级”和“单元(文件)级”。也就是说,如果项目没有任何变化,那么整个项目工件都可以复用,无需重新构建其任何单元(在大型 C++ 应用中,一个解决方案中通常包含多个项目,涵盖数百个单元)。如果拥有更细粒度的单元级缓存(在 C++ 中,指的是缓存单个编译单元的 “obj” 文件),那么即使最终工件的依赖关系因单个单元的变化而发生了变化,我们也只需要重新执行已经变化的单元,同时从缓存中找到该单元的其余输出(就是实现复用)。这样加快了构建时间的同时,还减少了算力。
这种独特的通用“隐藏式”缓存方法释放了额外的功能,以探索开发生态系统的未来。这一领域高度分散,许多工具被用作大型构建执行的一部分,包括各种编译器、构建系统、软件语言工具、测试框架等。Incredibuild 的通用缓存方法未来可以作为统一的整体缓存解决方案,兼容构建中使用的所有工具,让这些工具也能充分利用缓存服务,同时还能帮助我们的客户加速:
整体缓存解决方案适用于多种不同的用例,这意味着围绕缓存服务开发的所有特性都可以服务于所有缓存用例。这种方法已经有许多用例,证明了我们大力投入构想这一强大的整体缓存方案是合理的。
点击此处,了解更多关于 Incredibuild 构建缓冲的信息,并可以获取免费试用 License 即刻加速您的构建!