您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

WebAssembly 火了!背后的 LLVM 功不可没!

时间:2023-08-21 14:09:17  来源:今日头条  作者:高级前端进阶

前面诸多文章中已经重点表达了自己对 WebAssembly 的浓厚兴趣,但是要深入学习 WebAssembly 就不得不说其背后的 LLVM ,这就是本文的主角。话不多说,直接开始!

1.什么是LLVM

LLVM,全称为 Low Level Virtual machine, 是一个用于构建高度优化的编译器(compilers)、优化器(optimizers)和运行时(run-time environments)环境的工具包。

类 C 语言使用 Clang 前端,组件使用 LLVM 将 C、C++、Objective-C 和 Objective-C++ 代码编译成 LLVM 位码(bitcode),最终编译成目标文件。

Clang:是一个C语言、C++、Objective-C语言的轻量级编译器,源代码通过BSD协议发布。Clang支持普通lambda表达式、返回类型的简化处理等诸多特性。

Image from Jacopo Mangiavacchi via Medium

LLVM 的核心是一个用于以编程方式创建机器本机代码的库。 开发人员使用 API 以称为中间表示或 LLVM IR (LLVM Intermediate Representation)的格式生成指令,然后 LLVM 可以将 IR 编译成独立的二进制文件或对代码执行 JIT(Just-in-Time)编译以在另一个程序的上下文中运行,例如:该语言的解释器或运行时。

LLVM 标志是一个双足飞龙、龙具有力量、速度和智慧的内涵。

LLVM 的 API 为开发编程语言中的许多常见结构和模式提供了原语。 例如,几乎每种语言都有函数和全局变量的概念,而且许多语言都有协程和 C 外部函数接口。 LLVM 在其 IR 中将函数和全局变量作为标准元素,并具有创建协程和与 C 库接口的能力。

 

比如上面的示例中是一个LLVM 的中间表示 (IR) 的示例。右边是一个简单的C程序,左边是由 Clang 编译器翻译成 LLVM IR 的相同代码

目前 LLVM 在 Github 上有 18.8K 的 star、7.1k 的 fork、2800+的代码贡献者。

2.LLVM:专为可移植性而设计

要理解 LLVM,可与 C 语言类比。C 被描述为一种可移植的高级汇编语言,因为它具有可以紧密映射到系统硬件的结构,并且几乎已被成功移植到各个系统的架构。 但是 C 作为一种可移植的汇编语言并非为特定目的而设计

相比之下,LLVM 的 IR 从一开始就被设计成一个可移植的组件,即通过提供独立于任何特定机器体系结构的原语

整数类型不限于底层硬件的最大位宽(例如 32 位或 64 位)。 开发者可以根据需要使用尽可能多的位来创建原始整数类型,如128 位整数,而不必担心制作输出以匹配特定处理器的指令集, LLVM 默认实现。

LLVM 的架构设计使其更容易支持现在和未来的各种硬件。 例如,IBM 最近贡献代码以支持其 z/OS、linux on Power、以及用于 LLVM 的 C、C++ 和 Fortran 项目的 AIX 架构。

3.编程语言如何使用 LLVM方式

LLVM 最常见的用例是作为语言的提前编译器(AOT,即Ahead-of-Time)。 例如,Clang 提前将 C 和 C++ 编译为本机二进制文件。

3.1 使用 LLVM 进行即时编译

有些情况需要在运行时动态生成代码,而不是提前编译。 例如,Julia 语言对其代码进行 JIT 编译,因为需要快速运行并通过 REP或交互式命令与用户交互。

Numba 是用于 Python/ target=_blank class=infotextkey>Python 的数学加速包,JIT 将选定的 Python 函数即时编译为机器代码。部分开发者正在尝试将 LLVM 用作 JIT 的新方法,例如:编译 PostgreSQL 查询,从而将性能提高五倍。

 

如上图:Numba 使用 LLVM 即时编译数字代码并加速其执行。 JIT 加速的 sum2d 函数完成其执行速度比常规 Python 代码快约 139 倍。

3.2 使用 LLVM 自动优化代码

LLVM 不只是将 IR(Intermediate Representation) 编译为本机代码。 开发者还可以通过编程方式指示它以高度粒度优化代码,一直到链接过程。 优化可能非常激进,包括内联函数、消除无用代码(包括未使用的类型声明和函数参数)以及展开循环等等。

LLVM的强大之处在于不必开发者关心,LLVM 可以自动处理优化,或者根据开发者指令关闭特定优化等。

3.3 具有 LLVM 的领域特定语言

LLVM 已被用于为许多通用语言生成编译器,也可用于生成高度垂直或专用于问题域的语言。这是 LLVM 最值得称赞的地方,它降低了创建语言的难度,而且表现良好。

Emscripten 项目采用 LLVM IR 代码并将其转换为 JAVAScript,理论上允许任何具有 LLVM 后端的语言导出可在浏览器中运行的代码。

使用 LLVM 的另一种场景是向现有语言添加特定领域的扩展。 Nvidia 使用 LLVM 创建 Nvidia CUDA 编译器,允许语言添加对 CUDA 的本地支持,将其编译为正在生成的本地代码的一部分(更快),而不是通过它附带的库调用(更慢)。

4.使用各种语言的 LLVM

使用 LLVM 的典型方法是使用开发者熟悉的语言编写代码(当然,它支持 LLVM 的库)。

两种常见的语言选择是 C 和 C++。 许多 LLVM 开发人员默认使用这两者之一,原因如下:

  • LLVM 本身是用 C++ 编写的。
  • LLVM 的 API 在 C 和 C++ 中可用。
  • 许多语言的开发往往以 C/C++ 为基础

尽管如此,这两种语言并不是唯一的选择。 许多语言都可以本地调用 C 库,因此理论上可以使用任何此类语言执行 LLVM 开发。目前许多语言、运行时都有这样的库,包括 C#/.NET/Mono、Rust、Haskell、OCAML、Node.js、Go 和 Python等等。

需要注意的是,一些与 LLVM 语言绑定可能不如其他语言那么完整。 例如,对于 Python,有很多选择,但每个选择的完整性和实用性各不相同。

如果对如何使用 LLVM 库来构建语言有兴趣,LLVM 有一个教程,使用 C++ 或 OCAML,它会引导你创建一种称为 Kaleidoscope 的简单语言。

5.LLVM 不做什么

LLVM 不解析语言的语法, 许多工具已经可以完成这项工作,例如: lex/yacc、flex/bison、Lark 和 ANTLR,所以 LLVM是解析与编译分离的。

有 LLVM 不提供原语的语言的公共部分。 如:LLVM 不提供垃圾收集器机制,但它确实提供了实现垃圾收集的工具,方法是允许用元数据标记代码,从而更容易编写垃圾收集器。

但是,不排除 LLVM 最终可能添加用于实现垃圾收集的本机机制的可能性。

6.和LLVM相关的WebAssembly运行时

Wasmer

Wasmer 是在非浏览器上下文中运行 Wasm 的一种方式,提供基于 WebAssembly 的超轻量级容器。专注于支持在任何平台上运行 WASM 代码,为其他跨平台运行时(例如 Java)提供了潜在的替代方案。

 

Wasmer 在 GitHub 上将自己描述为“一个快速且安全的 WebAssembly 运行时,它使超轻量级容器可以在任何地方运行:从桌面到云、边缘和物联网IOT设备”。

Wasmer使用熟悉的工具和喜欢的语言,将所有内容编译为 WebAssembly。可以在任何操作系统上运行它或将其嵌入到其他语言中。

WasmEdge

WasmEdge 是一个轻量级、高性能和可扩展的 WebAssembly 运行时, 它是当今号称最快的 Wasm VM。WasmEdge的用例包括:现代 Web 应用程序架构(同构和 Jamstack 应用程序)、边缘云上的微服务、无服务器 SaaS API、嵌入式功能、智能合约和智能设备等方方面面。

 

 

WasmEdge 是世界上第一个正式的 CNCF WebAssembly 运行时项目,可以设想它将作为边缘云的关键任务轻量级运行时,在 CNCF 的开源云计算领域发挥重要作用。

WasmEdge 可以运行从 C/C++、Rust、Swift、AssemblyScript 或 Kotlin 源代码编译的标准 WebAssembly 字节码程序。同时,它还受到标准语言和编译器工具链的支持,例如 LLVM、Rustc 和 emscripten。

更多关于Wasmer、WasmEdge的内容可以继续在我的主页阅读,已经单独撰文《全网最火的5+优秀 WebAssembly 运行时!》进行详细介绍。

7.获取源代码并构建 LLVM教程

下载 LLVM

git clone --depth 1 https://github.com/llvm/llvm-project.git

配置和构建 LLVM 和 Clang

cd llvm-project
cmake -S llvm -B build -G <generator> [options]

可用的 generator 包括:Ninja、Unix Makefiles 、Visual Studio、Xcode

执行 build

cmake --build . [--target <target>]
// 默认target(即 cmake --build . 或 make)将构建所有 LLVM。

基本构建

一个基本的 CMake 和构建/测试调用,它只构建 LLVM 而没有其他子项目:

cmake -S llvm -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug
ninja -C build check-llvm

上面代码将使用调试信息设置 LLVM 构建,然后编译 LLVM 并运行 LLVM 测试。

独立构建

独立构建针对系统上已存在的 clang 或 llvm 库的预构建版本构建子项目。

可以使用来自 llvm 项目(如上所述)的标准签出的源代码来进行独立构建,但也可以从发布页面上可用的 tarball 中构建。

对于独立构建,必须有一个 llvm 安装,它被正确配置为可以被其他项目的独立构建使用。 这可能是一个发行版提供的 LLVM 安装,或者可以自己构建它,如下所示:

cmake -G Ninja -S path/to/llvm-project/llvm -B $builddir 
      -DLLVM_INSTALL_UTILS=ON 
      -DCMAKE_INSTALL_PREFIX=/path/to/llvm/install/prefix 
      < other options >

ninja -C $builddir install

安装 llvm 后,要独立构建配置项目,如下调用 CMake:

cmake -G Ninja -S path/to/llvm-project/$subproj 
      -B $buildir_subproj 
      -DLLVM_EXTERNAL_LIT=/path/to/lit 

7.本文总结

本文主要带着大家了解 WebAssembly 学习路上遇到的LLVM 。文章从什么是LLVM、LLVM:为可移植性而设计、编程语言如何使用 LLVM、使用各种语言的 LLVM、LLVM 不做什么等方面逐步深入。

因为篇幅有限,文章并没有过多展开,如果有兴趣,可以在我的主页继续阅读,同时文末的参考资料提供了大量优秀文档以供学习。最后,欢迎大家点赞、评论、转发、收藏!

 

参考资料

原文链接:
https://www.infoworld.com/article/3247799/what-is-llvm-the-power-behind-swift-rust-clang-and-more.html

原文作者:Serdar Yegulalp

翻译&修改:头条号高级前端进阶

封面图:
https://hacks.mozilla.org/2017/02/creating-and-working-with-webassembly-modules/

https://www.heavy.ai/technical-glossary/llvm

https://github.com/llvm/llvm-project

https://llvm.org/

https://llvm.org/docs/GettingStarted.html

https://www.toutiao.com/article/7208714402630058531/

https://github.com/WasmEdge/WasmEdge



Tags:WebAssembly   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
Rust 编译为WebAssembly 在前端项目中使用
前言最近,不是加大了对Rust相关文章的输出吗,在评论区或者私信区。有一些不同的声音说:“Rust没有前途,然后...."。其实呢,看一个技术是否有需要学习的动力。想必大家的底层理由...【详细内容】
2023-10-27  Search: WebAssembly  点击:(248)  评论:(0)  加入收藏
2023 年 WebAssembly 现状:第四种 Web 语言
2023 年度 WebAssembly 现状调查结果出炉,下面就来看看 2023 年的 WebAssembly 发展的怎么样了!WebAssembly 是一种可移植、低级别的字节码语言,旨在提供一种通用的编译目标,以...【详细内容】
2023-10-20  Search: WebAssembly  点击:(259)  评论:(0)  加入收藏
通过WebAssembly,C++率先打响虚拟 DOM 第一枪!
前言本文主要和大家讨论 asm-dom,即通过 WebAssembly 技术 C++ 率先支持虚拟DOM。在年初,我也确实使用 WebAssembly 将客户端应用成功移植到了 Web,这也是为什么我一直对 WebAs...【详细内容】
2023-08-22  Search: WebAssembly  点击:(284)  评论:(0)  加入收藏
WebAssembly 火了!背后的 LLVM 功不可没!
前面诸多文章中已经重点表达了自己对 WebAssembly 的浓厚兴趣,但是要深入学习 WebAssembly 就不得不说其背后的 LLVM ,这就是本文的主角。话不多说,直接开始!1.什么是LLVMLLVM,全...【详细内容】
2023-08-21  Search: WebAssembly  点击:(149)  评论:(0)  加入收藏
最流行的 WebAssembly 语言,会是 JavaScript 吗?
对于网络平台而言,WebAssembly 的出现无疑是意义重大的,它能让各种语言编写的代码以接近原生的速度在 Web 中运行&mdash;&mdash;那么在各种语言中,Java 会是其中最流行的吗?原文...【详细内容】
2023-05-09  Search: WebAssembly  点击:(334)  评论:(0)  加入收藏
WebAssembly终极指南
WebAssembly(又名Wasm)已被证明在浏览器中运行得非常好。它被广泛用作提高速度和安全性的一种方式,尤其是直接在浏览器中运行的应用程序的计算简单性,特别是使用 JavaScript 以...【详细内容】
2023-05-06  Search: WebAssembly  点击:(257)  评论:(0)  加入收藏
人们在用 WebAssembly 构建什么应用?
WebAssembly (WASM) 在过去几年一直是一个流行词。 这是一项引起广泛关注但在实践中应用较少的技术。 我一直很好奇它的现状,所以我调查并总结了我的发现。 其中一些可能会让...【详细内容】
2023-01-07  Search: WebAssembly  点击:(319)  评论:(0)  加入收藏
WebAssembly 如何演进成为“浏览器第二编程语言”?
WebAssembly 无疑是近年来让人最为兴奋的新技术之一,它虽始于浏览器但已经开始不断地被各个语言及平台所集成。在实际的工业化落地中,区块链、边缘计算、游戏及图像视频等多...【详细内容】
2020-08-14  Search: WebAssembly  点击:(265)  评论:(0)  加入收藏
为什么每个人都在谈论 WebAssembly
了解有关在 Web 浏览器中运行任何代码的最新方法的更多信息。-- Mike Bursell(作者) 如果你还没有听说过 WebAssembly ,那么你很快就会知道。这是业界最保密的秘密之一,但它无...【详细内容】
2020-01-27  Search: WebAssembly  点击:(343)  评论:(0)  加入收藏
▌简易百科推荐
即将过时的 5 种软件开发技能!
作者 | Eran Yahav编译 | 言征出品 | 51CTO技术栈(微信号:blog51cto) 时至今日,AI编码工具已经进化到足够强大了吗?这未必好回答,但从2023 年 Stack Overflow 上的调查数据来看,44%...【详细内容】
2024-04-03    51CTO  Tags:软件开发   点击:(5)  评论:(0)  加入收藏
跳转链接代码怎么写?
在网页开发中,跳转链接是一项常见的功能。然而,对于非技术人员来说,编写跳转链接代码可能会显得有些困难。不用担心!我们可以借助外链平台来简化操作,即使没有编程经验,也能轻松实...【详细内容】
2024-03-27  蓝色天纪    Tags:跳转链接   点击:(12)  评论:(0)  加入收藏
中台亡了,问题到底出在哪里?
曾几何时,中台一度被当做“变革灵药”,嫁接在“前台作战单元”和“后台资源部门”之间,实现企业各业务线的“打通”和全域业务能力集成,提高开发和服务效率。但在中台如火如荼之...【详细内容】
2024-03-27  dbaplus社群    Tags:中台   点击:(8)  评论:(0)  加入收藏
员工写了个比删库更可怕的Bug!
想必大家都听说过删库跑路吧,我之前一直把它当一个段子来看。可万万没想到,就在昨天,我们公司的某位员工,竟然写了一个比删库更可怕的 Bug!给大家分享一下(不是公开处刑),希望朋友们...【详细内容】
2024-03-26  dbaplus社群    Tags:Bug   点击:(5)  评论:(0)  加入收藏
我们一起聊聊什么是正向代理和反向代理
从字面意思上看,代理就是代替处理的意思,一个对象有能力代替另一个对象处理某一件事。代理,这个词在我们的日常生活中也不陌生,比如在购物、旅游等场景中,我们经常会委托别人代替...【详细内容】
2024-03-26  萤火架构  微信公众号  Tags:正向代理   点击:(10)  评论:(0)  加入收藏
看一遍就理解:IO模型详解
前言大家好,我是程序员田螺。今天我们一起来学习IO模型。在本文开始前呢,先问问大家几个问题哈~什么是IO呢?什么是阻塞非阻塞IO?什么是同步异步IO?什么是IO多路复用?select/epoll...【详细内容】
2024-03-26  捡田螺的小男孩  微信公众号  Tags:IO模型   点击:(8)  评论:(0)  加入收藏
为什么都说 HashMap 是线程不安全的?
做Java开发的人,应该都用过 HashMap 这种集合。今天就和大家来聊聊,为什么 HashMap 是线程不安全的。1.HashMap 数据结构简单来说,HashMap 基于哈希表实现。它使用键的哈希码来...【详细内容】
2024-03-22  Java技术指北  微信公众号  Tags:HashMap   点击:(11)  评论:(0)  加入收藏
如何从头开始编写LoRA代码,这有一份教程
选自 lightning.ai作者:Sebastian Raschka机器之心编译编辑:陈萍作者表示:在各种有效的 LLM 微调方法中,LoRA 仍然是他的首选。LoRA(Low-Rank Adaptation)作为一种用于微调 LLM(大...【详细内容】
2024-03-21  机器之心Pro    Tags:LoRA   点击:(12)  评论:(0)  加入收藏
这样搭建日志中心,传统的ELK就扔了吧!
最近客户有个新需求,就是想查看网站的访问情况。由于网站没有做google的统计和百度的统计,所以访问情况,只能通过日志查看,通过脚本的形式给客户导出也不太实际,给客户写个简单的...【详细内容】
2024-03-20  dbaplus社群    Tags:日志   点击:(4)  评论:(0)  加入收藏
Kubernetes 究竟有没有 LTS?
从一个有趣的问题引出很多人都在关注的 Kubernetes LTS 的问题。有趣的问题2019 年,一个名为 apiserver LoopbackClient Server cert expired after 1 year[1] 的 issue 中提...【详细内容】
2024-03-15  云原生散修  微信公众号  Tags:Kubernetes   点击:(6)  评论:(0)  加入收藏
站内最新
站内热门
站内头条