目前和未来的缓存构建

说起来可能有点反直觉,有时候不运行反而可以帮助我们加快速度,这正是网络浏览器运行的指导原则。不必在页面上加载所有内容,缓存的元素已经存在,不需要每次访问网站或网页时都重新加载。页面加载速度越快,浏览器的工作量就越少,最终结果也是一样的。

不运行总是比运行更快

对于软件开发中的缓存,这一指导原则同样适用。在此情况下,缓存可以带来四点好处:

  1. 明显加速开发;
  2. 降低成本,利用云资源进行计算时尤为明显,包括在完成本地构建时也适用,甚至可以扩展到 CI 服务器许可证,因为每个 CI 服务器可以并行完成更多的构建;
  3. 鼓励开发人员采用所需构建时间较长而经常避免的最佳实践,例如使用特性分支和频繁设置分支,每次引入小提交,频繁从仓库中提取变更等;
  4. 从 CI 的角度来看,构建时间越短,每次提交时构建就会左移(即:缩短时间),对开发人员的响应时间就越快,因此可以从容地应对紧要时刻(执行的构建越多,缓存“热度”就越高(即:缓存使用次数就越多),效率就越高),漏洞解决的时间就越快,上市时间就越快等等。

目前缺少哪些软件构建缓存方法?

缓存可以分为多个等级,不同等级对性能的影响也不同。缓存粒度越细(例如,缓存整个代码库、缓存几行代码、缓存整个脚本的对比),性能就越好,降低的成本也就越多。

因此,在构思如何缓存构建工件时,能够缓存和复用最终工件(如可执行文件和库)固然不错,但您也应该考虑到更细粒度级。缓存还应包括中间工件,C++ 对象文件、调试信息以及构建的其他方面,如单元测试输出和自定义构建命令等。

依赖关系的负担

缓存的一大驱动原理是:为了在编译期间成功复用缓存工件,当前任务必须具备与先前缓存的输出工件明确相关的输入依赖项。

为此,在任务中若要将工件存入缓存,该任务必须关联可以触发该缓存工件创建的所有输入依赖项。一般情况下,创建一个唯一的哈希 ID 来代表所有任务依赖项,包括输入文件、环境变量、命令行参数和其他输入等,就可以实现关联。该哈希 ID 将代表可以触发特定工件的所有依赖项。

只有当所有相关的输入依赖项都与原先执行任务对应的哈希值相同时,执行的任务才能复用先前缓存的工件。

目前常用的方法为了满足此要求,又给用户和我们想要缓存的工具/编译器带来了负担:

  • 用户负担,为了实现缓存,一些构建工具要求用户在其构建脚本中显式包括构建将要执行的每个任务的所有输入依赖项,这样做需要(用户完成)大量的工作,决定并显式编写整个产品依赖关系。此外采用这种方法,需要深入了解产品的结构和依赖关系,同时要求由引入新代码的开发人员强制维护这些依赖关系。虽然这种方法在新建产品时可能较为可行,但对于大型项目来说,要完成整个流程的难度非常大,还可能导致构建错误,特别是在持续需要强制执行显式声明的开发过程中。
  • 工具负担,一些工具内置了提供输入依赖关系的运行时服务,例如编译器的预处理功能。具有预处理能力的编译器允许用户确定编译任务的输入依赖关系。但问题是,这种方法需要逐个编译器实现。并非所有工具都具有预处理能力(例如:缓存单元测试),而且,在每个编译的任务上,仅仅是执行用于确定任务依赖关系的预处理进程,就会给构建机器带来计算负担,导致机器延长构建时间。在不同主机之间共享缓存时,例如一组开发人员共享缓存工件或一组持续集成节点,这些限制因素会变得更加复杂。

Incredibuild 的专利缓存方法

Incredibuild 的独特缓存构建法主要基于自身平台强大且经过实践验证的并行分发技术,注入进程的底层系统钩子(类似于反病毒软件的工作原理)。利用该技术,Incredibuild 可以自动映射读取到的每个文件或进程访问的其他输入,使其可供无缝使用和共享,以确定任务依赖关系,减轻用户负担和工具负担。

其工作原理如下:

  • 执行一个 Process(示例采用 C++ 编译进程);
  • Incredibuild 将系统钩子注入进程,使其能够监测编译进程正在使用的所有输入(文件夹、注册表标志、环境变量等);
  • 编译进程运行时,Incredibuild 会自动确定该进程所需的所有输入以及该进程创建的所有内容(输出);
  • 所有输入经过哈希处理,在输入及其生成的输出之间建立关联。然后将哈希值和输出都存入高速缓存中,哈希值则用作相应任务输出的索引 ID;
  • 缓存在网络上的多个用户之间共享之后,其作用会显著放大,用户可以复用在网络中任何地方创建的输出,而不必再次重建。

这种利用系统钩子无缝跟踪进程依赖关系进行缓存的方法是一种全新的缓存方法(美国专利局认定此方法在技术上具有创新性,可以申请专利)。

在 Visual Studio 中使用的案例

让我们以 Visual Studio C++ 为例,来分析演示 Incredibuild 的工作原理,缓存将分为“方案级”、“项目级”和“单元(文件)级”。也就是说,如果项目没有任何变化,那么整个项目工件都可以复用,无需重新构建其任何单元(在大型 C++ 应用中,一个解决方案中通常包含多个项目,涵盖数百个单元)。如果拥有更细粒度的单元级缓存(在 C++ 中,指的是缓存单个编译单元的 “obj” 文件),那么即使最终工件的依赖关系因单个单元的变化而发生了变化,我们也只需要重新执行已经变化的单元,同时从缓存中找到该单元的其余输出(就是实现复用)。这样加快了构建时间的同时,还减少了算力。

未来愿景

这种独特的通用“隐藏式”缓存方法释放了额外的功能,以探索开发生态系统的未来。这一领域高度分散,许多工具被用作大型构建执行的一部分,包括各种编译器、构建系统、软件语言工具、测试框架等。Incredibuild 的通用缓存方法未来可以作为统一的整体缓存解决方案,兼容构建中使用的所有工具,让这些工具也能充分利用缓存服务,同时还能帮助我们的客户加速:

  • 其他软件语言和编译器;
  • 其他计算用例,如各种测试框架、代码分析等;
  • 在编译速度更快的语言(如 C#)时,减少构建工作量;
  • 支持按顺序处理非并行工作;
  • CI 进程中还包括用户自定义步骤,如自定义构建步骤、构建脚本、自制工具等。

整体缓存解决方案适用于多种不同的用例,这意味着围绕缓存服务开发的所有特性都可以服务于所有缓存用例。这种方法已经有许多用例,证明了我们大力投入构想这一强大的整体缓存方案是合理的。

点击此处,了解更多关于 Incredibuild 构建缓冲的信息,并可以获取免费试用 License 即刻加速您的构建!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/106979.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python-pptx教程之一从零开始生成PPT文件

简介 python-pptx是一个用于创建、读取和更新PowerPoint(.pptx)文件的python库。 典型的用途是根据动态内容(如数据库查询、分析数据等),将这些内容自动化生成PowerPoint演示文稿,将数据可视化&#xff0c…

为什么引入偏向锁、轻量级锁,介绍下升级流程

Synchronized Synchronized 在 jdk1.6 版本之前,是通过重量级锁的方式来实现线程之间锁的竞争。之所以称它为重量级锁,是因为它的底层底层依赖操作系统的 Mutex Lock 来实现互斥功能。(如图)Mutex 是系统方法,由于权限…

【公益案例展】奇安信补天漏洞响应平台——凝聚白帽子志愿力量

‍ 奇安信公益案例 本项目案例由奇安信投递并参与数据猿与上海大数据联盟联合推出的 #榜样的力量# 《2023中国数据智能产业最具社会责任感企业》榜单/奖项”评选。 ‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 我国网络安全行业存在人才奇缺、政企机构安全能力不足的现…

winodos下使用VS2022编译eclipse-paho.mqtt.c并演示简单使用的 demo

本文演示C语言如何使用eclipse-paho.mqtt.c库,包含自行编译库的步骤或者下载编译好的文件。 1.下载paho.mqtt.c库源码(zip 文件) 到官网选择C版本的paho源码进行下载 Eclipse Paho | The Eclipse Foundation 或者到下述连接下载 Releases ec…

二维码智慧门牌管理系统升级解决方案:采集项目的建立与运用

文章目录 前言一、采集项目的建立二、采集项目的运用三、采集项目的意义 前言 在二维码智慧门牌管理系统的升级过程中,一个至关重要的环节是采集项目的建立与运用。采集项目是新建采集任务的前提,同时也是整个系统升级的关键步骤。其意义近似于现实中的…

布隆过滤器(Bloom Filter)初学习

目录 1、布隆过滤器是什么 2、布隆过滤器的优缺点 3、使用场景 4、⭐基于Redis的布隆过滤器插件安装 4.1 下载布隆过滤器 4.2 创建文件夹并上传文件 4.3 安装gcc 4.4 解压RedisBloom压缩包 4.5 在解压好的文件夹下输入make 4.6 将编译的好的插件拷贝到docker redis容…

火柴排队.

题意:给两列火柴,可以交换任意相邻的火柴,使得(ai-bi)^2的和最小,求最小交换次数。 分析:使得(ai-bi)^2的和最小,即a^2-2abb^2的和最小,那么使得2ab最大,就可…

荣电集团与钕希科技签署全面战略合作

10月26日,荣电集团(以下简称荣电)与钕希科技南京有限公司(以下简称钕希科技)今天在合肥市签署全面战略合作协议,联合进军混合现实(Mixed Reality,以下简称MR)空间计算高科…

爬虫批量下载科研论文(SciHub)

系列文章目录 利用 eutils 实现自动下载序列文件 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 系列文章目录前言一、获取文献信息二、下载文献PDF文件参考 前言 大家好✨,这里是bio🦖。…

底层驱动day8作业

代码&#xff1a; //驱动程序 #include<linux/init.h> #include<linux/module.h> #include<linux/of.h> #include<linux/of_gpio.h> #include<linux/gpio.h> #include<linux/timer.h>struct device_node *dnode; //unsigned int gpiono; …

【云原生】portainer管理多个独立docker服务器

目录 一、portainer简介 二、安装Portainer 1.1 内网环境下&#xff1a; 1.1.1 方式1&#xff1a;命令行运行 1.1.2 方式2&#xff1a;通过compose-file来启动 2.1 配置本地主机&#xff08;node-1&#xff09; 3.1 配置其他主机&#xff08;被node-1管理的节点服务器&…

RabbitMQ基础

目录 RabbitMQ的可靠性投递 确保消息正确地发送至 RabbitMQ 确保消息接收方消费了消息 流程分析 1.生产者发送消息给Broker 2.交换机路由消息到队列 3.消息存储在队列 4.消费者订阅并消费消息 三个重要概念 RabbitMQ集群模式 RabbitMQ的可靠性投递 在 RabbitMQ 中&a…

TS中类型别名和接口区别

在很多场景下&#xff0c;interface 和 type都能使用&#xff0c;因此两者在很多时候会被混淆&#xff1a; 接口可以通过之间的继承&#xff0c;实现多种接口的组合 使用类型别名也可以实现多种的&#xff0c;通过&连接,有差异&#xff1a; 子接口中不能重新覆盖父接口中…

迭代器的封装与反向迭代器

一、反向迭代器 在list模拟实现的过程中&#xff0c;第一次接触了迭代器的封装&#xff0c;将list的指针封装成了一个新的类型&#xff0c;并且以迭代器的基本功能对其进行了运算符重载 反向迭代器是对正向迭代器的封装&#xff0c;并且体现了泛型编程的思想&#xff0c;任意…

0基础学习PyFlink——用户自定义函数之UDAF

大纲 UDAF入参并非表中一行&#xff08;Row&#xff09;的集合计算每个人考了几门课计算每门课有几个人考试计算每个人的平均分计算每课的平均分计算每个人的最高分和最低分 入参是表中一行&#xff08;Row&#xff09;的集合计算每个人的最高分、最低分以及所属的课程计算每课…

中文编程工具免费版下载,中文开发语言工具免费版下载

中文编程工具免费版下载&#xff0c;中文开发语言工具免费版下载 中文编程工具开发的实际部分案例如下图 编程系统化课程总目录及明细&#xff0c;点击进入了解详情。 https://blog.csdn.net/qq_29129627/article/details/134073098?spm1001.2014.3001.5502

栈、队列、矩阵的总结

栈的应用 括号匹配 表达式求值&#xff08;中缀&#xff0c;后缀&#xff09; 中缀转后缀&#xff08;机算&#xff09; 中缀机算 后缀机算 总结 特殊矩阵 对称矩阵的压缩存储 三角矩阵 三对角矩阵 稀疏矩阵的压缩存储

龙芯3A5000上安装微信

原文链接&#xff1a;龙芯3A5000上安装微信 hello&#xff0c;大家好啊&#xff0c;今天给大家带来一篇在龙芯3A5000上安装微信的文章&#xff0c;主要给大家展示一下在龙芯架构上使用微信的情况&#xff0c;看看内置浏览器、看一看、小程序等是否能正常打开使用。 1、查看系统…

Hadoop 请求数据长度 Requested Data length 超过配置的最大值

一、问题 现象 Spark 任务速度变慢&#xff0c;也不失败。 DataNode 内存足够 CPU 负载不高 GC 时间也不长。 查看 DataNode 日志&#xff0c;发现有些日志出现很多 Netty RPC 超时。超时的 destination 是一个 NameNode 节点&#xff0c;然后查看 NameNode 节点的日志&…

28 行为型模式-中介者模式

1 中介者模式介绍 2 中介者模式原理 3 中介者模式实现 /*** 抽象中介者**/ public interface Mediator {//处理同事对象注册与转发同事对象信息的方法void apply(String key); }/*** 具体中介者**/ public class MediatorImpl implements Mediator {Overridepublic void apply…