0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

介绍WebAssembly现存的一些风险和他们的应对方法

工程师邓生 来源:觉学社 作者:张汉东 2022-09-21 09:30 次阅读

标准化进展非常缓慢。为此 Fermyon 加入了 字节码联盟 亲自推动标准化进程,并通过构建 Spin 代码实现来充分利用标准

语言支持不够。Fermyon 认为前 20 种语言中至少有 15 种必须完全支持 WebAssembly 以及 WASI 和组件,才能正确地认为 WebAssembly 被很好地采用。Fermyon 采取的立场是将注意力集中在最受欢迎的语言上,这就是为什么使用 Rust 而不是 C 或Zig。

这方面也有一些好消息:

语言支持正在迅速增长,今年C#Python和Ruby都增加了支持

wasi 支持现在是进入 wasm 游戏领域的筹码

在主流实现语言未能发挥作用的地方,该语言的替代实现正在加紧发展,比如 tinygo 对于 wasm 的支持就超越了 go

生态系统不是可选的。WebAssembly 有望成为下一波计算浪潮,但除非 Fermyon 能围绕它建立生态系统,所以 Fermyon 正在努力联合相关其他企业合作共建社区。

社区实现碎片化。(比如 deno 和其他非标准化实现,文章没有明说)。可悲的是,有时这仅仅是由于无知和不参与:“我们不知道有一个标准为此而出现”。所以目前发布的组件规范(正在进行中,但正在迅速成熟)旨在解决这类问题,这个标准使得在不同的主机实现之间共享 WebAssembly 二进制文件成为可能。

还有一个不幸的趋势,即一些开发人员选择与组件模型相反的工作,创建与他们自己的主机运行时的强链接。走这条路一方面会导致平台锁定,另一方面会毫无意义地重新编写相同的代码(针对略有不同的主机进行工具化)。幸运的是,那些准备最好的人(Fastly、Mozilla、Microsoft)反而选择推动互操作性标准以造福所有人。这是正确的第一步。

为了阻止破坏性的碎片化“手榴弹”,我们必须增加社会压力,不要我行我素,而要坚持互操作性标准。做到这一点的一个关键方法是彼此公开合作(通过字节码联盟、W3 和 CNCF 等组织),不仅要创建和实施标准,还要创建对话论坛

Fermyon 的愿景是,在五年内,WebAssembly 将成为常态,而不是小众市场。新一波应用程序将能够利用 WebAssembly 的速度、安全性和组件模型。为了实现这一目标,我们每个人都可以发挥作用。

Wasmtime 1.0 性能概览

近日字节码联盟发布了 wasmtime 1.0 性能概览[2] 的一篇文章,为将在 9.20号发布的 wasmtime 1.0 稳定版做前期铺垫,介绍了 wasmtime 团队近期在编译器和运行时中所做的工作。这里只做重点摘要,并非全文翻译,对细节感兴趣的可进一步参阅原文。

什么是性能

让 Wasmtime 和 Cranelift 变得更快意味着什么?所谓的“快”是什么意思?

Cranelift 也被用于 Rust Debug 模式编译后端

当 Wasmtime 执行 Wasm 程序时,CPU既执行从Wasm字节码编译的本地指令,也执行 "Wasmtime Runtime "的一部分,Wasmtime Runtime 用于维护数据结构以帮助实现Wasm语义。这两部分的执行有两个阶段:启动初始化(Wasm代码的编译,和运行时的初始化)和 稳态(steady-state)执行。这两个层面的四个组合都对性能有一定的影响,可以分别进行优化。

Compiler (Cranelift) Runtime (Wasmtime)
启动阶段 代码编译时间 Wasm 模块实例化时间
稳态阶段 生成代码的速度 运行时的基本速度

wasmtime 对于改善这四个象限中的每一项都做了大量工作。

Wasm 模块实例化

WebAssembly 之所以安全是因为wasm 模块每个实例与生俱来的隔离性。为了有效地利用这种隔离性,Wasm的一些应用将每一个工作单元实例化为一个新的实例,例如服务器上每个传入的请求。因此,极快的模块实例化是像Wasmtime这样的Wasm VM的一个关键要求。

现在 wasmtime 的模块实例化速度已经被优化到了微秒级别。这是如何做到的呢?

虚拟内存技术

在过去,wasmtime 是通过为 wasm 应用初始化一大块内存(通过malloc或mmap或一些其他分配器),然后将数据复制到正确的位置。

现在,是从现代计算机使用的虚拟内存技术获得灵感,实现了一个 实例分配器[3]使用了mmap 、madvise 和写时复制(copy-on-write)的技术将实例化的成本大大的降低了。

延迟初始化

Wasmtime运行时在开始执行已编译的Wasm代码之前,要花费大量时间来初始化数据结构。所以,团队为函数引用表和它们所指向的函数闭包对象实现了延迟初始化[4]。

优化结果

SpiderMonkey.wasm 的实例化时间从大约2毫秒到5微秒,快了400倍。

运行时性能

Wasm 执行过程中的大部分 CPU 时间通常花在Wasm程序本身,或它调用的 "hostcalls"(这是Wasmtime用户插入Wasmtime的代码,无法直接控制),除此之外,Wasmtime本身有一些部分在某些情况下必须运行,这部分代码就是 Wasmtime Runtime 的性能优化之处。

加速栈走查(Stack-Walking)

之前,为了让Wasmtime列举所有的栈帧(stackframes),Cranelift编译器产生了所谓的 "unwind info"。这是一种元数据,描述了编译后的代码将在任意给定点上把值放在栈中。利用这些元数据,Wasmtime的 "unwinder"能够逆向程序状态:它理解一个活动函数每次调用的栈帧,最终找出谁调用了它,并在栈上迭代,直到它到达Wasm的初始入口。整个过程非常慢。

团队对此进行了改进,确保始终保持一个帧指针的链表,从而达到栈走查像遍历链表那么简单。这种性能改进是一个巨大的质量改进:它允许启用栈跟踪,并大幅提高Wasmtime的健壮性。

加速多任务协作 与 代际(Epoch) 中断

Wasmtime的一个常见用例是同时并发运行许多不同的 WebAssembly guests,并在它们之间设置时间片。Wasmtime内置支持在一个异步事件循环上运行对Wasm的调用。

Wasmtime 用户在这种情况下可能遇到的一个问题是如何限制 Wasm 程序的执行时间。通常,当与事件循环异步运行时,计算密集型任务应拆分为多个段,以便事件循环不会停止超过最大“时间片”。

通过将 Wasm 字节码标准编译为本地机器代码,Wasm 中的循环成为编译代码中的循环,并运行尽可能多的迭代,没有限制。如果用户从事件循环中调用此函数,则该事件循环可能会无限期停止。

因此,特别是在运行不受信任的代码时,Wasmtime 用户必须建立一种在一定时间限制后重新获得控制权的方法。所以 Wasmtime 必须提供一种在某个时间点中断 Wasm 执行的方法。

之前,实现这一行为的主要方式是通过“燃料(fuel)”。这是一种机制,通过该机制,已编译的 Wasm 代码增加了对“操作”进行计数的代码,根据限制检查当前计数,如果超出限制,则返回给调用者或事件循环。“燃料(fuel)”是一种有效的机制,但它成本很高:它需要用“计数”来扩充每一段代码,并经常将该计数存储到内存中并检查它。

团队使用了基于代际的中断[5]取代了 “燃料(fuel)”机制,性能提升了两倍。

使用 “燃料”机制还是代际中断,是一种权衡。“燃料”机制更加精准,而代际中断性能更好。

Cranelift 编译代码的质量

Cranelift 用于将Wasm字节码编译成计算机可以直接执行的本地机器代码。

寄存器分配器改造:regalloc2

在过去的一年里,wasmtime引入了新的寄存器分配器 regalloc2[6]。寄存器分配器是编译器的一个部分,它为程序中的值分配存储位置。在真正的CPU中,指令对寄存器中的数据进行操作,寄存器是一些小的存储位置,每个位置可以容纳一个值(例如,一个64位的数字)。寄存器分配器决定在什么时候将哪些值保存在哪些寄存器中。做好这一点可以大大改善程序的性能,因为它意味着更少的数值移动。WebAssembly,作为一个抽象的、与硬件无关的虚拟机,没有大多数指令的输入和输出位置的概念。

regalloc2的设计是为了支持更高级的算法,以决定如何向寄存器分配数值。当引入时,它将SpiderMonkey.wasm的运行时性能提高了约5%,将另一个CPU密集型基准测试bz2的性能提高了4%。

更好的模式管理:新的后端、ISLE和持续的调整

指令选择问题是指选择最佳的CPU指令来实现一个给定的程序行为。因为每个CPU都有自己独特的指令集,而且这些指令可以以许多不同的方式组合,这是一个非常难解决的组合难题。Cranelift最初采用了一种新的编译器后端设计,可以实现更高级的模式匹配,目前采取的方法是用模式匹配DSL(特定领域语言)来表达底层的指令,这样我们就可以更容易地调整这些模式。

未来:中端优化

在未来,我们计划为Cranelift引入更先进的中端优化。中端优化器 "是编译器的一部分,在程序被 "降级"为机器特定的形式之前(也就是在指令选择之前),以各种方式对程序进行转换,使其更快。有一套经典的优化方法,几乎所有的编译器都会执行,包括简化常数表达式(1+1变成2)等基本规则。但也有许多更复杂和微妙的转换。

Cranelift: 编译时优化

除了优化Cranelift生成的代码,编译过程本身如果太慢,那么Wasmtime可能需要很长的时间来启动新的代码,将会阻碍生产力(对于Wasm开发人员)和响应能力(对于访问新应用程序的最终用户)。因此,编译器的速度是一个重要的指标。

广义上讲,我们可以通过在后端关键部分选择更好的算法来提高编译时间,如寄存器分配器或优化通道,或通过做一般的程序优化,如减少内存使用。

regalloc2

切换到 regalloc2 显着改善了编译时间,因为寄存器分配占编译时间的很大一部分:测量单线程时间(不是并行编译),SpiderMonkey.wasm 的构建速度提高了 6%,bz2 的构建速度提高了 10%。

中端优化器:将多个passes合并为一

算法重新设计也可以大大缩短编译时间。在我们的中端优化器原型中,我们对编译器设计的相关部分采取了一种新的方法:几个不同的 "程序",或以某种方式改造程序的特定算法,被合并成一个统一的框架,只对程序进行一次处理。

标准程序优化

一种特别有效的提高速度的改变是减少内存的分配和使用。程序分配的内存越少,它的运行速度就越快,至少有两个原因:内存分配器本身可能很慢,而且使用更多的内存也会导致更多的缓冲区未命中和内存流量。由于其多线程编译模式,Cranelift也倾向于对分配器施加特别大的压力。

总结

高性能是任何希望成为构建高效、持久系统的基础的软件的一个关键方面。如果 WebAssembly 想要成功,它的运行速度必须能达到与本地代码竞争的水平。这也是 wasmtime 性能优化的终极目标。

通过该篇文章我们简单了解了 Wasmtime 和 Cranelift 性能优化的相关工作,以及当前 wasmtime 1.0 的性能状态(详细数据见原文)。后续的文章将介绍该团队如何确保 Wasmtime 安全以及编译器生成正确的代码。



审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • cpu
    cpu
    +关注

    关注

    68

    文章

    10412

    浏览量

    206465
  • 中断
    +关注

    关注

    5

    文章

    884

    浏览量

    41020
  • python
    +关注

    关注

    51

    文章

    4667

    浏览量

    83441
  • 虚拟内存
    +关注

    关注

    0

    文章

    70

    浏览量

    8018

原文标题:WebAssembly 动态 | WebAssembly 的发展风险及Wasmtime 1.0 性能概览

文章出处:【微信号:Rust语言中文社区,微信公众号:Rust语言中文社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    电源芯片短路恢复过冲的风险应对措施

    电源芯片短路恢复过冲的风险应对措施 电源芯片是电子产品中非常重要的组成部分,其稳定工作对整个电子设备的正常运行至关重要。然而,电源芯片在使用过程中可能会遇到短路和过冲的风险,给设备带来的损害甚至
    的头像 发表于 02-06 09:46 545次阅读

    车用SiC碳化硅的五大难点和应对方

    车用SiC碳化硅的五大难点和应对方案近年来,包括SiC在内的第三代半导体器件在汽车上的应用比例与日俱增。但在专业人士看来,这并不会是一个简单的事情。一以车用引线框架来看,尽管Si、碳化硅/氮化镓引线
    的头像 发表于 01-06 14:22 444次阅读
    车用SiC碳化硅的五大难点和<b class='flag-5'>应对方</b>案

    PID自动控制回路的振荡问题与应对方法

    在工业自动化控制领域,PID自动控制回路的应用非常广泛。然而,在使用过程中,我们常常会遇到各种振荡问题,如同相位振荡、异相位振荡和非平滑振荡等。这些问题不仅会导致装置的不稳定,还可能影响整个生产过程的安全和效率。本文将分享这三种振荡的特征及相应的应对方法,以供参考。
    的头像 发表于 12-28 09:10 3687次阅读
    PID自动控制回路的振荡问题与<b class='flag-5'>应对方法</b>

    电源电压变化对晶振性能的影响以及应对方法

    电源电压变化对晶振性能的影响以及应对方法  电源电压的变化是指电源输入电压的波动或变化,它可能产生一系列的问题,对晶振的性能和工作稳定性产生影响。本文将详细讨论电源电压变化对晶振的影响,并提供应对方法
    的头像 发表于 12-18 14:09 494次阅读

    云服务器被攻击应对方法

    当云服务器受到攻击时,采取适当的应对策略是关键,以确保系统的安全和可用性。下面,小编给大家简单总结一下云服务器被攻击应对方法: 1、监控和检测:部署实时监控系统,定期审查日志,以便及时发现异常活动
    的头像 发表于 12-06 17:44 457次阅读

    减少静电产生和降低击穿风险方法和材料

    介绍一些常见的方法和材料,以帮助我们更好地了解如何减少静电产生并降低击穿风险。 一、减少静电产生的方法: 要减少静电的产生,我们可以采取以下
    的头像 发表于 11-29 16:30 335次阅读

    ECG子系统设计主要挑战及应对方

    电子发烧友网站提供《ECG子系统设计主要挑战及应对方案.pdf》资料免费下载
    发表于 11-23 10:43 0次下载
    ECG子系统设计主要挑战及<b class='flag-5'>应对方</b>案

    开关电源噪声的应对方法

    引言:上一节简述了如何从根本上降低DC-DC的开关噪声,即振铃,本节简述从另一角度消解DC-DC的噪声的几种方法(上节的方式可以理解为前级静噪手段,本节则是后级静噪手段,即电源输出端)。
    发表于 08-30 16:29 683次阅读
    开关电源噪声的<b class='flag-5'>应对方法</b>

    ARM指令集体系结构(ISA)的一些功能介绍

    本指南介绍了特定于每个ARM指令集体系结构(ISA)的一些功能,并考虑了哪些应用程序最好地利用了这些功能。该指南的重点是Cortex-R。然而,我们也考虑Cortex-A和Cortex-M,在帮
    发表于 08-02 07:39

    WebAssembly技术_编译ffmpeg(ubuntu20.04)

    WebAssembly并不是直接用汇编语言,而提供了抓换机制(LLVM IR),把高级别的语言(C,C++和Rust)编译为WebAssembly,以便有机会在浏览器中运行。主要是解决目前JS语言的效率问题,设计立足点为快速,内存安全和开放。所以是一种运行机制,一种新的字
    的头像 发表于 07-14 10:29 1603次阅读
    <b class='flag-5'>WebAssembly</b>技术_编译ffmpeg(ubuntu20.04)

    基于WebAssembly构建Web端音视频通话引擎

    为我们从实践中来介绍WebAssembly、WebCodecs、WebTransport等技术在音视频行业的价值以及优势。 大家好,我叫田建华。今天分享的主题是基于WebAssembly构建Web
    的头像 发表于 06-26 15:56 471次阅读
    基于<b class='flag-5'>WebAssembly</b>构建Web端音视频通话引擎

    商业版数据库断供风险愈发扩大,浅谈 GaussDB 与国内企业的应对方

    ,给企业带来了巨大的挑战和压力。如何应对这一风险,保障企业数据的安全和可用性?国产数据库是否能够成为商业版数据库的替代方案?本文将以华为云数据库 GaussDB 为例,浅谈商业版数据库的断供风险以及国产数据库的重要性。 商业
    的头像 发表于 06-21 11:14 203次阅读
    商业版数据库断供<b class='flag-5'>风险</b>愈发扩大,浅谈 GaussDB 与国内企业的<b class='flag-5'>应对方</b>式

    一些模电笔记

    一些模电笔记
    发表于 06-09 22:33

    网络突发环路你的应对方法是什么?

    网工都遇到过网络环路,遇到这个情况,你的应对方法是什么?我了解到大部分的初阶网工,最开始都只能用拔插网线和重启观测法来排除回路。
    的头像 发表于 05-22 10:10 1656次阅读
    网络突发环路你的<b class='flag-5'>应对方法</b>是什么?

    人工智能训练数据集:误区、挑战与应对方法

    人工智能训练数据集是人工智能技术发展中至关重要的一环。然而,在构建和使用数据集时,我们常常会遇到一些误区和挑战,这些问题可能会影响数据集的质量和使用效果。本文将探讨人工智能训练数据集的误区、挑战以及应对方法
    的头像 发表于 04-27 17:50 696次阅读