< 返回版块

ChaosBot 发表于 2018-10-09 12:43

Tags:rustnews

JavaScript和WebAssembly函数调用性能提升

JavaScript和WebAssembly这两个语言之间函数调用是出了名的慢,但是最近这种情况已经得到了改善。在最新版本的Firefox Beta中,JS和WebAssembly之间的调用比非内联JS到JS函数调用要快。万岁!🎉

在最新的在Firefox Nightly工作中,一共优化了两个方向的调用从JavaScript到WebAssembly,从WebAssembly到JavaScript,而且还优化了WebAssembly调用内置函数的性能。

所有的优化都是为了减轻浏览器引擎的工作压力。这些改进一共分为两组:

  • 减少登记(Reducing bookkeeping),减少了调用栈帧
  • 切断中介(Cutting out intermediaries),函数调用采用尽可能直接的方式

一、如何优化WebAssembly到JavaScript的调用?

  • 浏览器引擎需要处理的内容包含两种:字节码(解释器生成)和机器码(JIT生成),这就好比是两片独立的大陆
  • 引擎需要在这两片「大陆」之间穿梭,以便统筹所有需要的信息。为了组织其工作,引擎有两个文件夹来记录这些信息。(比如SpiderMonkey引擎中,这些文件夹叫做activations)
  • 每次切换到不同的「大陆」,引擎都会启用新的文件夹,问题是,要启动一个文件夹必须通过C++调用,这就增加了成本。
  • 再最初增加WebAssembly支持的时候,相当于是给引擎增加了第三块「大陆」
  • 所以,WebAssembly调用js的过程就多了两个阻碍: 创建了不必要的文件夹和增加了C++调用成本
  • 优化手段: 将JIT-JS「大陆」和WebAssembly「大陆」合并在一起。

二、如何优化JavaScript到WebAssembly调用?

  • 即便在JIT编译之后,js和webassembly都使用机器码,但还存在一些问题。比如调用js动态类型。
  • wasm是静态类型,不希望付出运行时开销,当js获取的参数是动态的,也就是说,它把参数放到堆内存(装箱),wasm不知道该如何处理它
  • 所以在传给wasm之前,引擎会将装箱的参数值取出来,存到寄存器里,要做到这一点,还是需要C++。即便不需要C++,但这个过程也是没法取消的。
  • 优化手段: (使用C++ stub 代码)去掉了「中介(trampoline)」,当javascript调用webassembly时,装箱的值就被取出来放到了合适的位置,等待wasm直接使用。

三、更快的JavaScript到WebAssembly调用:单态(Monomorphic)调用

单态调用是指每次都调用相同的函数。在js中,存在每次都使用完全相同类型的参数来调用该函数。如果可以编写代码以便JavaScript始终将相同的类型传递给相同的WebAssembly导出函数,那么您的调用将非常快。实际上,这些调用比许多JavaScript到JavaScript调用要快。

在未来,可能会为JavaScript添加内联WebAssemly的支持。

四、如何优化WebAssembly到内置函数的调用

内置函数是浏览器提供的函数,如Math.random。有些内置函数是JS本身实现的,这种叫做自托管。有些是C++实现的,不同的浏览器引擎,有不同的实现,这方面并不统一。如果是自托管的内置函数,WebAssembly调用的时候就能用到前面说的优化,但是遇到C++实现的函数,则又回到了解放前。为此,专门为这样的内置函数构建了一条特殊的直达「通道」,允许在WebAssembly调用C++实现的内置函数时,使用该特殊通道,增加性能。

目前只支持Math相关的内置函数,这是因为WebAssembly只支持整数和浮点数。但是对于dom处理等内置函数来说则效果不佳,因此调用相关函数的时候必须使用js,这就是wasm-bindgen所要做的。

但是WebAssembly的一些实验性支持类型也会逐渐登录浏览器,一旦这些类型稳定,那么WebAssembly就可以不经过js直接调用那些内置函数了。所以当前的优化工作,在未来也会适用于其他内置函数。

但是仍然有一些内置的函数需要使用js,这些函数的问题由host-bindings来解决。

以上。

原文


RAII优于Haskell的bracket模式

本文比较了Haskell的bracket函数和RAII,并且阐述了bracket模式带来的问题(可能导致释放后还能使用的问题)和修复方式

原文


Noria:用于高性能Web应用程序的dynamic, partially-stateful data-flow

这是一种新的流数据流模型,可用于构建长期,低延迟的应用程序,例如Web应用程序。MIT、Norwegian大学等联合出品。

Noria是使用Rust实现的。

「论文」


寻找Rust中的Bug

作者写了一个库,用来快速检查Rust标准库中数据结构的Bug。

https://github.com/blt/bughunt-rust

作者发现了什么bug吗? 发现很多方法能在分配内存时发生恐慌。 Rust官方已经发了RFC 2116准备进行修复。

原文


氧化Python: 用Rust加速10倍

氧化(Oxidizing),目前在Rust社区是一个流行的词。

原文


「Job」创建高性能的Rust系统「非远程」

待遇: 旧金山| 130 - 175K +股权| 基础设施和HPC | 全职/现场

基于机器视觉,自动结帐,构建零售业未来。从头设计系统,可以部署到数百万零售商,已经在旧金山开设了测试商店。

目前正在寻找Rust工程师。

多好的工作呀!!!

原文


Heaptrack案例研究

作者基于Global Allocator尝试构建自己的内存分配器,

然而他在这个过程挖掘了一个工具:Heaptrack。可以用它来高亮内存的使用情况来帮助理解。

Heaptrack是linux下的一个工具(Mac和win可用),可以跟踪内存使用情况,并给出可视化报告。

本文就是介绍如何使用Heaptrack跟踪Rust代码中内存分配情况。

最终他得出结论:永远不要写自己的内存分配器,尽可能地使用heaptrack这种工具来优化代码吧。

原文

heaptrack


「视频」无恐惧多媒体编程

GStreamer是Linux世界中多媒体编程的首选框架,尤其用于嵌入式,但是传统都是C/C++来编写GStreamer的应用程序和插件。不幸的是,这种效率是以安全为代价的。即便是最熟练的C/C++开发人员也会在内存管理方面犯错,结果可能是灾难性的。线程安全是多媒体解决方案的核心,但是用C/C++极难实现。

在本次视频演讲中,Zeeshan介绍了使用GStreamer的Rust绑定如何安全、简单地编写多媒体应用程序。

原文


评论区

写评论

还没有评论

1 共 0 条评论, 1 页