我是如何提升 Rust 编译器的速度?
作者 | Nicholas Nethercote
译者 | 弯月,责编 | 伍杏玲
出品 | CSDN(ID:CSDNnews)
【CSDN 编者按】本文是Rust的核心研发人员,在本文中,他将分享一下再2019年,他在提升 Rust 编译器的速度上,做了哪些新的工作来优化它。
更快的Globals
libsyntax用一个全局数据结构Globals存储了3个表,分别存储了有关span(代码位置)、符号和数据清理(与宏扩展相关)的信息。访问这些表的代价很高,所以我找到了许多改进方法。
#59693(https://github.com/rust-lang/rust/pull/59693):AST中的每个元素都有一个span,描述了元素在原始源代码中的位置。
每个span由偏移、长度以及与宏扩展相关的值组成。这三个字段共占12个字节,考虑到它需要添加到AST的每个元素上,12个字节太多了,而且很多时候这三个字段并不需要这么多空间。
因此,编译器采用了只需4字节的压缩格式,而当长度超过4字节时则采用备用策略——将其存储到Globals中的哈希表中。而该PR将其改为了8个字节。这会稍稍增加内存的使用量,但上述备用策略的执行率可以从10-20%降低到不足1%,这可以加速许多工作负载,最大可以提升14%。
#61253(https://github.com/rust-lang/rust/pull/61253):有许多操作都需要访问数据清理信息,通常这些操作会调用两次甚至三次,因此会造成重复查找数据清理信息。该PR引入了组合操作,可以避免重复查找。这可以将packed-simd上的速度提高10%,对于普通工作负载效率可以提高3%。
#61484(https://github.com/rust-lang/rust/pull/61484):与上述#61253类似,只不过这个PR在许多基准测试中都赢得了提高2%的好成绩。
#60630(https://github.com/rust-lang/rust/pull/60630):编译器有一个驻留的字符串类型,名叫符号(symbol)。编译器对该类型的使用不太一致。因此,导致许多符号与普通字符串的比较需要逐个字符比较符号表中的字符串。
实际上,符号与符号的比较的开销很小,只需进行整数比较。该PR删除了符号与字符串的比较操作,强迫编译器更广泛地使用符号类型。(幸运的是,大多数引入的符号都使用了静态已知、预先驻留的字符串,因此没有额外的成本。)该PR在各种基准测试中赢得了高达1%的效率提升,而且符号的使用也更为一致。
#60815(https://github.com/rust-lang/rust/pull/60815):与上述#60630类似,该PR也在各项基准测试中赢得了高达1%的效率提升。
#60467、#60910、#61035、#60973:这些PR避免了一些不必要的符号,可以进一步将编译器的效率提高1%。
其他
以下各项提升没有统一的主题。
#57719(https://github.com/rust-lang/rust/pull/57719):该PR将一个常用的函数改成了内联函数,可以将一个工作负载的效率提高4%。
#58210(https://github.com/rust-lang/rust/pull/58210):该PR改变了一个常用的断言(仅在调试版本中有效),可以将一个工作负载的效率提高20%!
#58207(https://github.com/rust-lang/rust/pull/58207):上述我曾提到了字符串驻留。Rust编译器还会针对其他经常出现重复值的类型使用驻留,包括一种名叫LazyConst的类型。
然而,intern_lazy_const函数有很多Bug,而且没有真正执行驻留,它只是分配了一个新的LazyConst,而却不会检查之前是否遇到过!该PR修复了这个问题,大幅降低了内存使用率的峰值,而且页错误还减少了59%。
#59507(https://github.com/rust-lang/rust/pull/59507):该美化输出会针对每个缩进的空格调用write!,在某些工作负载上,缩进级别会超过100级。该PR能在绝大多数情况下将所有处理放到一个write!调用中。该PR可以在多个基准测试中体现出7%的提升。
#59626(https://github.com/rust-lang/rust/pull/59626):该PR更改了数据结构的预分配大小,以更好地满足实际需要,在某些工作负载上,可以将内存使用量的峰值减少20 MiB。
#61612(https://github.com/rust-lang/rust/pull/61612):该PR优化了解析器中的热路径,因为常量标志符会毫无目的地重复“这是不是一个关键字?”的测试,对于拥有大量常量的程序来说,该PR可以提升7%的性能。
分析改进
下面的改进涉及一些分析工具。
#59899(https://github.com/rust-lang/rust/pull/59899):为了让枚举变量从大到小列举,我修改了-Zprint-type-sizes的输出。该PR可以方便你看到超大的变量,特别是对于有许多变量的枚举。
#62110(https://github.com/rust-lang/rust/pull/62110):为了改进-Ztime-passes标志的输出,我删除了一些无用信息的输出,并添加了总编译时间的度量。
此外,我还改进了rustc-perf基准测试套件中的分析支持。首先,我添加了OProfile性能分析的支持。我承认至今我还没有发现显著的提升。在运行时,大约有一半的几率会出现错误,很让人失望。
其次,我添加了新版DHAT性能分析的支持。虽然这篇文章写自2019年,但值得一提的是,我于2018年对新DHAT的帮助做了一些改进,PR包括:#55167、#55346、#55383、#55384、#55501、#55525、#55556、#55574、#55604、#55777、#55558、#55745、#55778、#55905、#55906、#56268、#56090、#56269、#56336、#56369和#56737。
最后,我还写了一篇有关Rust性能所有基准的概要描:https://github.com/rust-lang-nursery/rustc-perf/blob/master/collector/benchmarks/README.md
流水线编译
上述改进(以及此前完成的所有改进)都属于微优化,也就是说,我使用分析数据来优化一小段代码。
但是,我们还应该考虑对Rust编译器速度进行更大规模的系统性改进。今年第二季度的时候,我曾与Alex Crichton在流水线编译项目上展开了合作,这一功能通过叠加依赖箱(crate)的编译,提升了构建多箱Rust项目时的并行度。没有流水线的编译如下图所示:
在使用了流水线后,编译如下图所示:
我承担了Rust编译器方面的工作,而Alex负责的是Cargo方面的工作。
如果你想了解其中的工作原理,以及使用方法和大量的测量数据,请阅读这篇文章:https://internals.rust-lang.org/t/evaluating-pipelined-rustc-compilation/10199
其效果高度依赖于项目的箱结构以及编译机器的配置。我们发现有些项目的性能提升可达1.84倍,而有些项目则没有任何提升。在最差的情况下,还有可能导致速度出现几乎可以忽略不计的减慢,但是无需担心,因为它不会导致任何额外的工作,只是改变了某些工作的顺序。
目前流水线编译还处于不稳定阶段,这篇文章记录了我们发现的问题:https://github.com/rust-lang/rust/issues/60988
今后的工作
我想在第三季度的时候,展开下列的工作:
对于流水线编译,我想尝试在编译器前端,尽早推动元数据的创建,这有可能会进一步提高速度。
Rust编译器经常使用memcpy,虽然不是直接使用,但生成的代码经常为了移动值或其他原因使用memcpy。编译器不会在“检查”阶段执行任何代码生成,通常有2-8%的指令会发生在memcpy中。我想了解其中的原因,并看看是否可以改进。一种可能性是编译器中移动了超大的类型;另一种可能性是代码生成有问题。如果是前一种情况,则很容易修复;如果是后一种,则难度较大。但是,如果能修改好的话,许多Rust程序都会受益。
增量编译的效率有时不是很理想。在某些工作负载上,即便做了很微小的修改,但是重新编译所需的时间与完整的非增量编译大致相同。也许我可以通过增量实现的一个小改动来提升性能。
我想看看解析器中是否还有其他可以改进的热路径,比如像#61612。
不过我还有各种Firefox的工作安排,不知道是否能顺利完成上述的所有工作。
原文:https://blog.mozilla.org/nnethercote/2019/07/17/how-to-speed-up-the-rust-compiler-in-2019/
本文为 CSDN 翻译,转载请注明来源出处。
四大项目,挑战Python全栈工程师?
https://edu.csdn.net/topic/python115?utm_source=csdn_bw
【END】
热 文 推 荐
☞阿里平头哥“生娃”!最强 RISC-V 处理器玄铁 910 诞生!
☞wxPython + PyOpenGL 打造三维数据分析的利器!| CSDN 博文精选
☞江苏互联网图鉴
☞特朗普要解禁华为?美七家科技公司联合要求恢复供货
☞博士毕业最高201万!华为顶级薪酬招“天才少年”
☞别再说学不会:超棒的Numpy可视化学习教程来了!
☞百度入局, 一文读懂年交易过4亿「超级链」究竟是什么?
☞无服务器计算,如何节省时间和成本?
中国第一程序员,微软得不到他就要毁了他!
点击阅读原文,输入关键词,即可搜索您想要的 CSDN 文章。
你点的每个“在看”,我都认真当成了喜欢
我是如何提升 Rust 编译器的速度?相关推荐
- AWS 聘用 Rust 编译器联合创始人,大企为何都爱 Rust?
整理 | 夕颜 图源 | 视觉中国 出品 | CSDN(ID:CSDNnews) 近日,AWS开源团队在一篇帖子中低调宣布,已聘用Rust编译器联合创始人Felix Klock.加入AWS后,他将与于 ...
- Ubuntu 22.04下加快rust的编译速度
在学习Rust的时候,相信不少人和我一样一直受Rust编译慢的问题困扰.最近阅读一篇写得相当不错的英文博客<Tips for Faster Rust Compile Times>,加上最近 ...
- 如何“主动出击”提升网站的收录速度?
网站的收录速度与排名都有着很大的关系,因为速度越快也意味着网站被收录的量和几率都会很大,更有利于网站排名提升.那么我们该如何提升网站收录的速度呢?下面就带大家一起来了解一下. 1.定期更新,提高创意 ...
- rust为什么显示不了国服_AWS偏爱Rust,已将Rust编译器团队负责人收入囊中
机器之心报道 作者:张倩.杜伟 近日,AWS 透露,该公司已经聘用了 Rust 编译器团队负责人之一 Felix Klock.该消息出自 AWS 开源团队于上周二发布的一篇文章<Why AWS ...
- rust风化速度_反驳《Golang、Rust的执行速度的对照,让人大吃一惊。》——不会别瞎说...
首先我无意引战,但是今天看到某位同学的文章里有某些错误,不得不指正一下. 1. 测量时间的时候我们使用 `std::time::SystemTime::elapsed` 即可,不必蹩脚的使用两个 sy ...
- 【Android优化篇】提升Activity加载速度的方法
文章转自:http://www.jianshu.com/p/2007ca0290d3 作者: CoderFan 前言 这个也是我面试遇到的问题,当时只回答了一种情况,异步加载数据,没想到别的方式,回来 ...
- Rust 越来越香了!AWS 雇佣 Rust 编译器团队负责人 Felix Klock
继微软转向 Rust 之后,又一巨头开始投入 Rust 的怀抱. 近日,亚马逊云服务 AWS 透露,该团队已聘请 Rust 编译器联合负责人 Felix Klock.Klock 之前曾在Mozilla ...
- 电脑开机太慢?这5个方法瞬间提升你的电脑速度
小伙伴们有没有发现,电脑用久了就会变得卡顿,开机速度也变慢了.刚买的新电脑开机只要5秒,用了很久的电脑开机可能要几十秒甚至更久. 电脑卡顿,让我们不仅工作效率低,玩游戏的时候也不痛快.别担心,今天小葱 ...
- linux usb 批量传输文件,一种Linux系统下提升usb批量传输速度的方法及系统与流程...
本发明涉及通信传输技术领域,具体地说是一种linux系统下提升usb批量传输速度的方法及系统. 背景技术: linux系统访问usb设备有两种方式:编写内核驱动模块ko和在用户空间编写程序,通过内核提 ...
最新文章
- Day 13 Python 一之helloworld
- php gd测试代码,PHP: GD - Manual
- amt630a芯片中文资料_甲基化芯片学习记录
- oracle禁止访问监听,关于ORACLE数据库监听自动停止解决一例
- 基于FPGA实践之呼吸灯(含程序)
- 【原创】pads2007 Layout 电气连接性检查过孔显示错误
- python 修改图片_Python实现批量修改图片格式和大小的方法【opencv库与PIL库】
- 微信小程序选项卡 点击导航内容切换 滑动内容导航切换
- github的健步如飞
- 神经计算棒python_神经计算棒-Movidius™ Neural Compute SDK Python API
- 目标检测概述-VOC COCO数据集 IOU AP NMS
- 虚拟专用网络安全技术
- HDU -2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(DP,贪心)
- HTML-内嵌框架-00
- Android10.0通知Notification的使用这一篇就够了
- js打印三角形超详解
- python入门教程NO.1 用python打印你的宠物小精灵吧
- VMware收费太贵?试试这款更轻量级的虚拟机,完全免费!
- C++经典41问(2个小时快速掌握C++)
- html字体左右摇动代码,CSS3 左右摇摆的文字动效