MLIR: 编译器基础架构重定义

MLIR: 编译器基础架构重定义
MLIR(多级中间表示)是语言(如 C)或库(如 TensorFlow)与编译器后端(如 LLVM)之间的中间表示 (IR) 系统。允许不同语言的不同编译器堆栈之间的代码重用以及其他性能和可用性优势。
MLIR 由Google开发为一个开源项目,主要是为了改进 TensorFlow 在不同后端的支持,但通常可用于任何语言。
背景
要了解 MLIR 的适用范围,需要简要概述 C、Java 和 Swift 等常用语言的编译器基础架构,然后继续介绍 TensorFlow 的编译器基础架构。这样,MLIR 的原理和可交付成果的想法就很清楚了。
编译器架构情况:
在这里插入图片描述

从 C 的编译器基础结构开始。C 编译器接收 C 代码,转换为抽象语法树 (AST),然后将其转换为 LLVM IR。AST 是一种树数据结构,其中节点表示算子等代码组件,叶节点表示数据。例如,像a+b这样的代码语句的抽象语法树如下:
在这里插入图片描述

随后,抽象语法树被转换为 LLVM IR(中间表示)。LLVM 是一种编译器基础架构,可将 LLVM IR 转换为机器代码。LLVM 是一种常用工具,是最流行的语言(如 C、C++、JAVA、Swift 等)的一部分。
所以,C代码的流程如下:
• C 代码由 C 编译器(如 GCC)转换为 Clang AST
• Clang AST 通过 C 编译器(如 GCC)转换为 LLVM IR
• LLVM IR 由 LLVM 转换为机器码
C 的这种编译策略存在一些问题,例如:
• 在 AST 中,将代码语句链接到代码行号或源代码的信息丢失了,因为 AST 无法存储此类信息。导致无法指向源代码的错误。一个常见的例子是,当发生segmentation fault时,错误信息并没有说明是源代码中的哪一行导致了这个问题。
• 由于 C 代码直接转换为 AST,不会进行特定于语言的优化。事实上,如果开发了 C 库,则在此流程中无法在编译器期间进行特定于库的优化。
Java 和 Swift 等语言采用了不同的方法来解决这个问题。
Java是第一个解决这个问题成功的语言。Java 的方法是将 Java 代码转换为 Java 字节码 (JavaBC),是 Java 的内部表示。正是在这种表示进行了 Java 特定和库特定的优化。在此之后,Java BC 被转换为 LLVM IR,后者被 LLVM 转换为机器代码。因此,Java 的方法是避免创建 AST,是任何程序的通用表示,因此创建了自己的格式,不仅解决了 C 的问题,而且使 Java 成为第一个独立于平台的语言。
Java 方法的一个问题是变得非常复杂,需要深入了解 LLVM 才能充分利用。这将现有资源发挥到极致,以获得最佳优化。
其它语言复制 Java 的技术是一个问题,所以后来,Swift 提出了自己的方法,并被广泛采用。
Swift代码被转换为 AST,其中 Swift 特定表示被转换为 Swift 的内部表示。正是在这一点上,所有语言特定的优化都完成了。随后,Swift IR 被转换为 LLVM IR,后者被 LLVM 获取并转换为机器代码。
这是一种相对简单的方法,解决了所有 C 的原始问题。在功能上,与 Java 的方法相同。Swift 的方法变得非常流行,并被改编成Rust等新语言。
此时的主要问题,每当创建一种新语言时,必须再次进行所有优化,例如程序流程优化、数据结构优化等(以前的语言已经完成)。唯一不同的是语言特定的优化。LLVM 负责机器级优化。因此,必须为每种语言再次创建整个管道。
如果仔细观察,语言仅在操作抽象和内部语言特定优化方面有所不同。为了帮助创建新的语言和库,Google TensorFlow 团队决定创建 MLIR(多级中间表示)。
实际上,这个问题是在 TensorFlow 中遇到的,谷歌并没有专门为 TF 解决这个问题,而是决定一劳永逸地修复编译器基础架构。
TensorFlow 的编译器基础架构:
在这里插入图片描述

流程如下:
• 可以使用API 之一(如 C++ 或 Python)来编写 TensorFlow 代码
• TensorFlow 代码被转换为 TF 图,Gappler(TensorFlow 中的一个模块)进行图级优化,包括几个机器学习特定的优化,如算子融合。
• 在此之后,TF 图被转换为其后端之一(替代 LLVM)的众多内部表示 (IR) 之一。
• TensorFlow 有许多后端,如 XLA(用于 TPU)、TF Lite(用于移动设备)等
问题是对于每个路径(如 XLA 和 TF Lite),开发人员必须重新实现所有优化,并且大多数优化是通用的,但代码重用是不可能的。这个问题将通过 MLIR 解决。
因此,MLIR 的流程如下图所示:
在这里插入图片描述

概括:
• 不同语言的相同编译器基础结构,不可重用
• 类似于 Swift 和其他语言中的编译器基础结构
• tensorflow 支持许多具有不同 IR 的后端,无需代码重用
• 目的是增加代码重用以快速适应新的硬件后端
• 中间 IR 用于捕获数据流信息并应用优化、比 LLVM 更好的源代码跟踪、灵活的设计、重用 LLVM 进行机器代码生成
使用 MLIR 的优势
使用 MLIR 的优势:
• 默认情况下源代码位置跟踪
• 默认情况下,所有功能都在多核上运行(使用 OpenMP)
• 更好地重用编译器堆栈的代码(用于新库和硬件),重用其它语言完成的优化
• 通过开发 CIL IR 为 C 提供更好的编译器堆栈
• 对于 TensorFlow,一条路径中的优化可以在其它路径中重用,从而实现大量代码重用。
内部关键思想
MLIR 的主要思想是:
• 没有预定义的类型或指令。这允许开发人员自定义数据类型和指令抽象
• 没有预定义的操作
• MLIR 中的基本对象是一种方言dialects,从实现的角度可以认为是一个类
• 需要定义指向 C++ 代码的方言dialects,方言dialects就像自定义语言的类
• 方言dialects有 3 部分:函数名、输入参数列表、输出参数列表
• 对于每种方言dialects,默认功能如类型检查、映射到 LLVM IR
• MLIR 默认支持线性代数运算,例如方言dialects之间的类型检查
• 语言被转换为带有方言dialects的形式
• 在这种形式(方言dialects集)上,执行优化
• 经过各种级别的lowering,方言dialects可以直接转换为LLVM IR
• 在 MLIR 中更好地使用 OpenMP,所有信息都可用
• 默认情况下,所有功能都在所有内核上运行(更好的系统使用)
• (优于 LLVM)每个操作数都有一个源代码内存地址属性,直接指向发生错误的源代码行
• 将使用 XLA 基础架构进行性能分析和剖析。
应用
MLIR用于改进 TensorFlow 编译器基础架构:

  1. 通过源代码跟踪改进 TF Lite 的生成
    编译流程如下:
    • TF代码
    • 方言dialects
    • 验证/优化
    • 用于 tf lite 后端的 tf lite 方言dialects
  2. 使用 MLIR 更改 XLA HLO 的路径
    编译流程如下:
    • tf
    • 方言dialects
    • 验证/优化
    • xla方言dialects
    • xla后端
    它将重用来自 TF Lite 路径的一些组件
  3. 使用 MLIR 支持新的编译器后端
    当一个新平台 P 出现并且它有一个新的后端 B 时,然后转换 TensorFlow 代码通过使用 TF Lite 和 XLA 的现有代码,转换为现有的方言dialects/IR。接下来,需要编写一个新的方言dialects集/IR(针对平台进行自定义优化)和转换代码,转换为平台后端编译器所需的 IR。
    MLIR 的使用使该过程更易于管理和快速。
    其它应用
    MLIR 是一种通用工具,可用于其它目的,例如:
    • 通过 MLIR 插入新的 IR 来解决 C 和 C++ 代码的问题
    • 新语言可以直接使用使用 MLIR 的现有语言的优化,因此开发新语言将变得容易和快速。
    • 一旦使用MLIR的系统实施,一组编译技术的创新可以被多个组轻松使用
    简而言之,LLVM 极大地创新了编译器生态系统,但现在 MLIR 通过利用 LLVM 的最佳部分实现更简单、更高效的编译器生态系统,从而进入了下一阶段。

热门文章

暂无图片
编程学习 ·

那些年让我们目瞪口呆的bug

程序员一生与bug奋战,可谓是杀敌无数,见怪不怪了!在某知识社交平台中,一个“有哪些让程序员目瞪口呆的bug”的话题引来了6700多万的阅读,可见程序员们对一个话题的敏感度有多高。 1、麻省理工“只能发500英里的邮件” …
暂无图片
编程学习 ·

redis的下载与安装

下载redis wget http://download.redis.io/releases/redis-5.0.0.tar.gz解压redis tar -zxvf redis-5.0.0.tar.gz编译 make安装 make install快链方便进入redis ln -s redis-5.0.0 redis
暂无图片
编程学习 ·

《大话数据结构》第三章学习笔记--线性表(一)

线性表的定义 线性表:零个或多个数据元素的有限序列。 线性表元素的个数n定义为线性表的长度。n为0时,为空表。 在比较复杂的线性表中,一个数据元素可以由若干个数据项组成。 线性表的存储结构 顺序存储结构 可以用C语言中的一维数组来…
暂无图片
编程学习 ·

对象的扩展

文章目录对象的扩展属性的简洁表示法属性名表达式方法的name属性属性的可枚举性和遍历可枚举性属性的遍历super关键字对象的扩展运算符解构赋值扩展运算符AggregateError错误对象对象的扩展 属性的简洁表示法 const foo bar; const baz {foo}; baz // {foo: "bar"…
暂无图片
编程学习 ·

让程序员最头疼的5种编程语言

世界上的编程语言,按照其应用领域,可以粗略地分成三类。 有的语言是多面手,在很多不同的领域都能派上用场。大家学过的编程语言很多都属于这一类,比如说 C,Java, Python。 有的语言专注于某一特定的领域&…
暂无图片
编程学习 ·

写论文注意事项

参考链接 给研究生修改了一篇论文后,该985博导几近崩溃…… 重点分析 摘要与结论几乎重合 这一条是我见过研究生论文中最常出现的事情,很多情况下,他们论文中摘要部分与结论部分重复率超过70%。对于摘要而言,首先要用一小句话引…
暂无图片
编程学习 ·

安卓 串口开发

上图: 上码: 在APP grable添加 // 串口 需要配合在项目build.gradle中的repositories添加 maven {url "https://jitpack.io" }implementation com.github.licheedev.Android-SerialPort-API:serialport:1.0.1implementation com.jakewhart…
暂无图片
编程学习 ·

2021-2027年中国铪市场调研与发展趋势分析报告

2021-2027年中国铪市场调研与发展趋势分析报告 本报告研究中国市场铪的生产、消费及进出口情况,重点关注在中国市场扮演重要角色的全球及本土铪生产商,呈现这些厂商在中国市场的铪销量、收入、价格、毛利率、市场份额等关键指标。此外,针对…
暂无图片
编程学习 ·

Aggressive cows题目翻译

描述&#xff1a; Farmer John has built a new long barn, with N (2 < N < 100,000) stalls.&#xff08;John农民已经新建了一个长畜棚带有N&#xff08;2<N<100000&#xff09;个牛棚&#xff09; The stalls are located along a straight line at positions…
暂无图片
编程学习 ·

剖析组建PMO的6个大坑︱PMO深度实践

随着事业环境因素的不断纷繁演进&#xff0c;项目时代正在悄悄来临。设立项目经理转岗、要求PMP等项目管理证书已是基操&#xff0c;越来越多的组织开始组建PMO团队&#xff0c;大有曾经公司纷纷建造中台的气质&#xff08;当然两者的本质并不相同&#xff0c;只是说明这个趋势…
暂无图片
编程学习 ·

Flowable入门系列文章118 - 进程实例 07

1、获取流程实例的变量 GET运行时/进程实例/ {processInstanceId} /变量/ {变量名} 表1.获取流程实例的变量 - URL参数 参数需要值描述processInstanceId是串将流程实例的id添加到变量中。变量名是串要获取的变量的名称。 表2.获取流程实例的变量 - 响应代码 响应码描述200指…
暂无图片
编程学习 ·

微信每天自动给女[男]朋友发早安和土味情话

微信通知&#xff0c;每天给女朋友发早安、情话、诗句、天气信息等~ 前言 之前逛GitHub的时候发现了一个自动签到的小工具&#xff0c;b站、掘金等都可以&#xff0c;我看了下源码发现也是很简洁&#xff0c;也尝试用了一下&#xff0c;配置也都很简单&#xff0c;主要是他有一…
暂无图片
编程学习 ·

C语言二分查找详解

二分查找是一种知名度很高的查找算法&#xff0c;在对有序数列进行查找时效率远高于传统的顺序查找。 下面这张动图对比了二者的效率差距。 二分查找的基本思想就是通过把目标数和当前数列的中间数进行比较&#xff0c;从而确定目标数是在中间数的左边还是右边&#xff0c;将查…
暂无图片
编程学习 ·

项目经理,你有什么优势吗?

大侠被一个问题问住了&#xff1a;你和别人比&#xff0c;你的优势是什么呢? 大侠听到这个问题后&#xff0c;脱口而出道&#xff1a;“项目管理能力和经验啊。” 听者抬头看了一下大侠&#xff0c;显然听者对大侠的这个回答不是很满意&#xff0c;但也没有继续追问。 大侠回家…
暂无图片
编程学习 ·

nginx的负载均衡和故障转移

#注&#xff1a;proxy_temp_path和proxy_cache_path指定的路径必须在同一分区 proxy_temp_path /data0/proxy_temp_dir; #设置Web缓存区名称为cache_one&#xff0c;内存缓存空间大小为200MB&#xff0c;1天没有被访问的内容自动清除&#xff0c;硬盘缓存空间大小为30GB。 pro…
暂无图片
编程学习 ·

业务逻辑漏洞

身份认证安全 绕过身份认证的几种方法 暴力破解 测试方法∶在没有验证码限制或者一次验证码可以多次使用的地方&#xff0c;可以分为以下几种情况︰ (1)爆破用户名。当输入的用户名不存在时&#xff0c;会显示请输入正确用户名&#xff0c;或者用户名不存在 (2)已知用户名。…