当前位置: 首页 > news >正文

提速Rust编译器!

Nethercote是一位研究Rust编译器的软件工程师。最近,他正在探索如何提升Rust编译器的性能,在他的博客文章中介绍了Rust编译器是如何将代码分割成代码生成单元(CGU)的以及rustc的性能加速。

他解释了不同数量和大小的CGU之间的权衡以及Rustc是如何使用LLVM并行化代码生成和优化的。此外,Nethercote还探索了一些形成和排序CGU的替代方法,并报告了他的实验结果。

Nethercote发现,很多时候,无法在编译速度、内存占用、编译体积和质量上都实现提升,一个指标的提升,经常伴随另一个性能指标的下降。尽管他没有发现比现有方法更明显的改进,但还是希望在未来继续研究这个问题。

如何提升Rust编译器速度?这篇文章或许能帮助到你!

1、LLVM:Rust编译加速的秘诀

Rust的MIR是HIR到LLVM IR的中间产物,将MIR转换为LLVM IR,然后将其传递给LLVM,从而生成机器代码。在此过程中,LLVM能通过处理多个模块实现并行。Rustc使用LLVM加速Rust的编译。我们称其中的每个模块为“代码生成单元(CGU)”。

图片

图:时间位于 x 轴上,每条水平线代表一个线程。主线程显示在顶部,标有 PID。它在开始时处于活动状态,时间足以产生另一个标记为 的线程rustc。rustc底部显示的线程在大部分执行过程中都处于活动状态。还有 16 个 LLVM 线程标记opt cgu.00为 到opt cgu.15,每个线程都会在短时间内处于活动状态。

CGU实际上是如何形成的呢?粗略地说,Rust 程序由许多函数组成,这些函数形成一个有向图,其中从一个函数到另一个函数的调用构成了一条边。我们需要将这个图分割成块(CGU),这是一个图分区问题。我们希望创建大小大致相等的 CGU(因此 LLVM 处理它们所需的时间长度大致相同),并最大限度地减少它们之间的边数(因为这使 LLVM 的工作更轻松,并带来更好的代码质量) 。

实际上,由于我们上面看到的阶梯效应,我们不希望 CGU 的大小完全相同。理想的情况是 CGU 大小存在与梯度相匹配的轻微梯度。这样,所有 CGU 将完全相同地完成处理,以实现最大程度的并行化。

合并之前的CGU(9个)

合并之前的CGU(9个)

Nethercote认为在合并之前“调整”CGU可能会有所帮助,在某些情况下将函数从一个CGU移动到另一个。例如,如果在CGU A中被调用f的叶函数(即不调用任何其他函数的叶函数)在CGU B中有一个调用方g,那么将f从A移动到B是有意义的,从而去除CGU间的边。(还有其他类似的情况涉及非叶函数,移动也有意义)。我实现了这一点,它给出了一些适度的改进,但我目前还没有决定它是否值得额外的复杂性。

调整之后的CGU(5个)

调整之后的CGU(5个)

在实现这一点的同时,我还花了一些时间来可视化调用图。我从GraphViz开始。这些图表对于非常小的程序来说看起来不错,但对于较大的程序来说,它们很快就变得无法读取和导航。我在Mastodon上抱怨过这一点,并得到了使用d2的建议,d2速度较慢,但图形可读性更强。

图片

2、后端并行方法的软肋

图划分是一个 NP 难题。有几种常见的算法,实现起来相当复杂。相反,rustc 做了一些更简单的事情。首先简单地为每个 Rust 模块创建一个 CGU:模块中的每个函数都放入同一个 CGU 中。然后,如果 CGU 数量超过限制(默认情况下,非增量构建为 16 个,增量构建为 256 个),它会重复合并两个最小的 CGU,直到达到限制。这种方法简单、快速,并以有用的方式利用特定领域的知识——程序模块往往提供良好的自然边界。

所有这一切都依赖于测量 CGU 大小的方法。目前使用CGU中的MIR语句的数量来估计LLVM处理CGU需要多长时间。这里有很大的设计空间,有许多其他可能的形成和规划CGU 的方法。

图片

这种转换对Rust众多语法糖进行了脱糖,并且极大精简了Rust的语法(但并非其语法子集),是观察和分析Rust代码的常用手段,尤其是在控制流图和借用检查等方面。

在这篇文章的最后,Nethercote提供了几个数据集的链接,每个数据集都记录了编译rust -performance基准时每个CGU的测量值。这些数据集包括许多测量静态代码大小的输入(独立变量),例如,函数数量和MIR数量等。

Nethercote试着用scikit-learn做一些基本的分析。并且,通过这些基本的分析,能让Nethercote仔细推敲到底应该搜集哪些测量值。

通过一系列的改进优化,他获得的最终数据集比刚开始时的数据更准确。但是,并没有通过这些数据获得多少实际的结果。实际上,每次我对测量的内容改变后都会得到完全不同的结果。

3、实现更快的Lexer

词法分析(lexical analysis)是编译器的第一个阶段,实现词法分析的代码称为lexer。

有人最近研究了logos(https://github.com/maciejhirsz/logos)这个在rust中广受欢迎的lexer。

此前,logos声称其目标是能比手动实现的lexer更快,作者提出了质疑,因为在他看来,通用性和性能无法兼得。因此,他一步步实现了lexer,探索了多种优化技巧,并与logos进行了多轮性能对比。

最终的结果表明,手动实现的基于状态机的lexer比logos实现了20%左右的性能提升。

4、从错误中学习:使用Rust实现DLL注入

Rust是一种注重安全性的编程语言,但在某些情况下,开发人员可能需要使用unsafe关键字来执行某些操作。unsafe可以提供更高的性能,但可能会牺牲安全性。因此,开发人员在使用时需要非常小心。几个使用unsafe的常见场景包括:访问裸指针、调用外部C函数等,并提供了一些建议和最佳实践,以确保在使用unsafe时不会引入潜在的安全隐患。

举个应用方面的例子:原来,作者一直在用C++编写逆向工具,但是,C++这门语言并不友好,于是研究了下如何使用Rust实现DLL注入的“工具”。

大致原理就是让Rust首先生成一个C样式的DLL,然后,使用unsafe操作裸指针,操作程序内存,最后实现DLL注入就可以了。

5、期待更准确的估计函数

Nethercote 希望具有数据分析专业知识的人可以做得更好,重点关注以下几个方面:

1)更匹配的估计函数

2)想要使编译器比现在更快,一个更好的估计函数也许不会达到预期的效果。我提出了一些更好的统计方法,但并没有提升编译速度,甚至变差。

3)CGU调度效果不可预测,你不能假设一个估计函数好几个百分点就会使编译器更快。话虽如此,我希望改进力度足够大,能够转化为实际的加速。

4)对于估计函数来说,最好高估CGU编译所需的时间,而不是低估。

5)我很担心过度拟合。数据集来自一台机器,但实际上,rustc会运行在不同的机器上,具有各种各样的体系结构和微体系结构。

6)这些数据集来自单一版本的rustc,使用单一版本的LLVM。我担心随着时间的推移准确性可能会漂移。

7)我更喜欢不太复杂且易于理解的估计函数。当前的函数非常简单,在大多数情况下只是增加了基本模块和语句的数量。例如:0大小的CGU应该别估计为花费非常接近于0的时间。

8)估计函数有一个明确的问题,即如果不考虑其内部公式,计算MIR语句可能非常不准确。特别是,单个MIR语句可能变得很长。举个例子:深度向量压力测试的MIR包含一条语句,该语句定义了包含超过100,000个元素的向量字面量。不出所料,当前的估计函数严重低估了编译这个基准所需的时间。

Nethercote最后提醒:希望以上的请求是合理的!

以下是上文提到的数据集:

  • 调试构建,主要基准测试

https://nnethercote.github.io/aux/2023/07/25/Debug-Primary.txt

  • 选择构建,主要基准

https://nnethercote.github.io/aux/2023/07/25/Opt-Primary.txt

  • 调试构建,二级基准测试

https://nnethercote.github.io/aux/2023/07/25/Debug-Secondary.txt

  • 选择构建,二级基准

https://nnethercote.github.io/aux/2023/07/25/Opt-Secondary.txt

  • 顺便说一句:在这些数据集中,主要基准测试比次要基准测试更重要,次要基准测试包括压力测试、微基准测试和其它不符合实际的代码。

相关内容拓展:(技术前沿)

近10年间,甚至连传统企业都开始大面积数字化时,我们发现开发内部工具的过程中,大量的页面、场景、组件等在不断重复,这种重复造轮子的工作,浪费工程师的大量时间。

针对这类问题,低代码把某些重复出现的场景、流程,具象化成一个个组件、api、数据库接口,避免了重复造轮子。极大的提高了程序员的生产效率。

推荐一款程序员都应该知道的软件JNPF快速开发平台,采用业内领先的SpringBoot微服务架构、支持SpringCloud模式,完善了平台的扩增基础,满足了系统快速开发、灵活拓展、无缝集成和高性能应用等综合能力;采用前后端分离模式,前端和后端的开发人员可分工合作负责不同板块,省事又便捷。

体验官网:https://www.jnpfsoft.com/?csdn,还没有了解低代码这项技术可以赶紧体验学习!

参考资料:

1.https://nnethercote.github.io/2023/07/25/how-to-speed-up-the-rust-compiler-data-analysis-assistance-requested.html

2.https://geo-ant.github.io/blog/2023/unsafe-rust-exploration/

3.https://nnethercote.github.io/2023/07/11/back-end-parallelism-in-the-rust-compiler.html

相关文章:

提速Rust编译器!

Nethercote是一位研究Rust编译器的软件工程师。最近,他正在探索如何提升Rust编译器的性能,在他的博客文章中介绍了Rust编译器是如何将代码分割成代码生成单元(CGU)的以及rustc的性能加速。 他解释了不同数量和大小的CGU之间的权衡…...

QT创建项目

可选择CMake或qmake...

基于vue3+webpack5+qiankun实现微前端

一 主应用改造(又称基座改造) 1 在主应用中安装qiankun(npm i qiankun -S) 2 在src下新建micro-app.js文件,用于存放所有子应用。 const microApps [// 当匹配到activeRule 的时候,请求获取entry资源,渲染到containe…...

华为OD真题--完美走位--带答案

2023华为OD统一考试(AB卷)题库清单-带答案(持续更新)or2023年华为OD真题机考题库大全-带答案(持续更新) 题目描述 输入一个长度为4的倍数的字符串Q,字符串中仅包含WASD四个字母。 将这个字符串中的连续子串…...

【AI】《动手学-深度学习-PyTorch版》笔记(十四):多层感知机

AI学习目录汇总 1、多层感知机网络结构 1.1 线性模型:softmax回归 在前面介绍过,使用softmax回归来处理分类问题时,每个输出通过都一个仿射函数计算,网络结构如下,输入和输出之间为全链接层: 1.2 多层感知机 多层感知机就是在输入和输出中间再添加一个或多个全链接…...

本地开发 npm 好用的http server、好用的web server、静态服务器

好用的web server总结 有时需要快速启动一个web 服务器(http服务器)来伺服静态网页,安装nginx又太繁琐,那么可以考虑使用npm serve、http-server、webpack-dev-server。 npm serve npm 的serve可以提供给http server功能&#…...

Gradio入门,并搭个鸡兔同笼问题小应用,附源码(MindOpt)

应用链接: https://979427749bc9ceec34.gradio.live 是公开访问链接,3天有效。 在modelscope中的创空间发布长期有效:https://modelscope.cn/studios/wuyoy520v01/MindOpt_Chicken-with-rabbit-cage/summary。 应用图如下,源代码见正文。 知…...

redis核心知识点简略笔记

value数据类型 string 二进制安全 list 有序、可重复 set 无序、不重复 hash field-value的map sorted set 不重复、通过double类型score分数排序 场景 string 计数器缓存分布式锁访问频率控制分布式session hash 购物车等对象属性灵活修改 list 定时排行榜 set 收藏 sorte…...

消息中间件 —— 初识Kafka

文章目录 1、Kafka简介1.1、消息队列1.1.1、为什么要有消息队列?1.1.2、消息队列1.1.3、消息队列的分类1.1.4、p2p 和 发布订阅MQ的比较1.1.5、消息系统的使用场景1.1.6、常见的消息系统 1.2、Kafka简介1.2.1、简介1.2.2、设计目标1.2.3、kafka核心的概念 2、Kafka的…...

Ceph集群安装部署

Ceph集群安装部署 目录 Ceph集群安装部署 1、环境准备 1.1 环境简介1.2 配置hosts解析(所有节点)1.3 配置时间同步2、安装docker(所有节点)3、配置镜像 3.1 下载ceph镜像(所有节点执行)3.2 搭建制作本地仓库(ceph-01节点执行)3.3 配置私有仓库(所有节点执行)3.4 为 Docker 镜像…...

PXC基于docker搭建mysql集群全过程

之前用mysql自带的bin-log复制,总是因为各种冲突,同步就阻塞掉了,一旦阻塞掉了,不主动发现,同步就终止了。还需要想办法手动去处理。所以考虑重新搭建集群。发现PXC方案不错,可以上两台,对服务器…...

项目知识点记录

1.使用druid连接池 使用properties配置文件: driverClassName com.mysql.cj.jdbc.Driver url jdbc:mysql://localhost:3306/book?useSSLtrue&setUnicodetrue&charsetEncodingUTF-8&serverTimezoneGMT%2B8 username root password 123456 #初始化链接数…...

【HDFS】ListenableFuture在HDFS中的应用

本文主要介绍以下内容: ListenableFuture提供的功能和基本使用方法;AsyncLogger、IPCLoggerChannel(它是AsyncLogger的子类)QuorumCall类一、ListenableFuture的基本使用 ListenableFuture 是 Guava 库中提供的一个接口,它扩展了 JDK 中的 Future 接口,并添加了异步任务…...

Databend 开源周报第 105 期

Databend 是一款现代云数仓。专为弹性和高效设计,为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务:https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展,遇到更贴近你心意的 Databend 。 Databend 轻量级…...

ArcGISPro随机森林自动化调参分类预测模型展示

更改ArcGISPro的python环境变量请参考文章 ArcGISPro中如何使用机器学习脚本_Z_W_H_的博客-CSDN博客 脚本文件如下 点击运行 结果展示 负类预测概率 正类预测概率 二值化概率 文件夹(模型验证结果) 数据集数据库 ROC曲线 由于个人数据量太少所以…...

科技资讯|苹果手机版Vision Pro头显专利曝光,内嵌苹果手机使用

根据美国商标和专利局(USPTO)公示的清单,苹果公司近日获得了一项头显相关的技术专利,展示了一款亲民款 Vision Pro 头显,可以将 iPhone 放置在头显内部充当屏幕。 根据patentlyapple 媒体报道,这是苹果公司…...

Linux服务器映射到本地磁盘

内容来自网友博客。 把linux服务器上的文件夹映射到本地作为一个磁盘来访问,步骤如下 一. samba的安装: sudo apt-get install samba // (sudo get temp root auth) sudo apt-get install smbfs //旧版本 sudo apt-get install cifs-utils //新版本 上…...

条条大路通罗马系列—— 使用 Hiredis-cluster 连接 Amazon ElastiCache for Redis 集群

前言 Amazon ElastiCache for Redis 是速度超快的内存数据存储,能够提供亚毫秒级延迟来支持 实时应用程序。适用于 Redis 的 ElastiCache 基于开源 Redis 构建,可与 Redis API 兼容,能够与 Redis 客户端配合工作,并使用开放的 Re…...

元宇宙核能发电VR模拟仿真实训教学为建设新型电力系统提供重要支撑

随着“碳达峰、碳中和”目标与建设新型能源体系的提出,在元宇宙环境下建设电力系统是未来发展的趋势。以物联网、区块链、数字孪生、混合现实等技术为主要代表的元宇宙技术体系及其在电力和能源系统中的应用,将会促进智能电网的发展,为建设新…...

我的Python教程:使用Pyecharts画柱状图

Pyecharts是一个用于生成 Echarts 图表的 Python 库。Echarts 是一个基于 JavaScript 的数据可视化库,提供了丰富的图表类型和交互功能。通过 Pyecharts,你可以使用 Python 代码生成各种类型的 Echarts 图表,例如折线图、柱状图、饼图、散点图…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…...

Spring Boot + MyBatis 集成支付宝支付流程

Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例&#xff08;电脑网站支付&#xff09; 1. 添加依赖 <!…...