随着深度学习的不断发展,AI 模型结构在快速演化,底层计算硬件技术更是层出不穷,对于广大开发者来说不仅要考虑如何在复杂多变的场景下有效的将算力发挥出来,还要应对 AI 框架的持续迭代。

AI 编译器就成了应对以上问题广受关注的技术方向,让用户仅需专注于上层模型开发,降低手工优化性能的人力开发成本,进一步压榨硬件性能空间。IR对于AI编译器来说是非常重要的一种数据结构鸭!!!


IR 中间表达

什么是IR

IR(Intermediate Representation)中间表示,是编译器中很重要的一种数据结构。编译器在完成前端工作以后,首先生成其自定义的 IR,并在此基础上执行各种优化算法,最后再生成目标代码。

从广义上看,编译器的运行过程中,中间节点的表示,都可以统称为 IR。从狭义上讲编译器的 IR,是指该编译器明确定义的一种具体的数据结构,这个数据结构通常还伴随着一种语言来表达程序,这个语言程序用来实现这个明确定义的 IR。大部分时间,不太严格区分这个明确定义的 IR 以及其伴随的语言程序,将其统称为 IR。

如图所示,在编译原理中,通常将编译器分为前端和后端。其中,前端会对所输入的程序进行词法分析、语法分析、语义分析,然后生成中间表达形式 IR。后端会对 IR 进行优化,然后生成目标代码。

例如:LLVM 把前端和后端给拆分出来,在中间层明确定义一种抽象的语言,这个语言就叫做 IR。定义了 IR 以后,前端的任务就是负责最终生成 IR,优化器则是负责优化生成的IR,而后端的任务就是把 IR 给转化成目标平台的语言。LLVM 的 IR 使用 LLVM assembly language 或称为 LLVM language 来实现 LLVM IR的类型系统,就指的是 LLVM assembly language 中的类型系统。

因此,编译器的前端,优化器,后端之间,唯一交换的数据结构类型就是 IR,通过 IR 来实现不同模块的解耦。有些IR还会为其专门起一个名字,比如:Open64的IR通常叫做WHIRL IR,方舟编译器的IR叫做MAPLE IR,LLVM则通常就称为LLVM IR。

IR的定义

IR 在通常情况下有两种用途,1)一种是用来做分析和变换,2)一种是直接用于解释执行。

编译器中,基于 IR 的分析和处理工作,前期阶段可以基于一些抽象层次比较高的语义,此时所需的 IR 更接近源代码。而在编译器后期阶段,则会使用低层次的、更加接近目标代码的语义。基于上述从高到低的层次抽象,IR 可以归结为三层:高层 HIR、中间层 MIR 和 底层 LIR。

  1. HIR

HIR(High IR)高层 IR,其主要负责基于源程序语言执行代码的分析和变换。假设要开发一款 IDE,主要功能包括:发现语法错误、分析符号之间的依赖关系(以便进行跳转、判断方法的重载等)、根据需要自动生成或修改一些代码(提供重构能力)。此时对 IR 的需求是能够准确表达源程序语言的语义即可。

其实,AST 和符号表就可以满足上述需求。也就是说,AST 也可以算作一种特殊的 IR。如果要开发 IDE、代码翻译工具(从一门语言翻译到另一门语言)、代码生成工具、代码统计工具等,使用 AST(加上符号表)即可。基于 HIR,可以执行高层次的代码优化,比如常数折叠、内联关联等。在 Java 和 Go 的编译器中,有不少基于 AST 执行的优化工作。

  1. MIR

MIR(Middle IR),独立于源程序语言和硬件架构执行代码分析和具体优化。大量的优化算法是通用的,没有必要依赖源程序语言的语法和语义,也没有必要依赖具体的硬件架构。这些优化包括部分算术优化、常量和变量传播、死代码删除等,实现分析和优化功能。

因为 MIR 跟源程序代码和目标程序代码都无关,所以在编译优化算法(Pass)过程中,通常是基于 MIR,比如三地址代码(Three Address Code,TAC)。

三地址代码 TAC 的特点:最多有三个地址(也就是变量),其中赋值符号的左边是用来写入,右边最多可以有两个地址和一个操作符,用于读取数据并计算。

  1. LIR

LIR(Low IR),依赖于底层具体硬件架构做优化和代码生成。其指令通常可以与机器指令一一对应,比较容易翻译成机器指令或汇编代码。因为 LIR 体现了具体硬件(如 CPU)架构的底层特征,因此可以执行与具体 CPU 架构相关的优化。

多层 IR 和单层 IR 比较起来,具有较为明显的优点:

  1. 可以提供更多的源程序语言的信息
  2. IR表达上更加地灵活,更加方便优化
  3. 使得优化算法和优化Pass执行更加高效

如在 LLVM 编译器里,会根据抽象层次从高到低,采用了前后端分离的三段结构,这样在为编译器添加新的语言支持或者新的目标平台支持的时候,就十分方便,大大减小了工程开销。而 LLVM IR 在这种前后端分离的三段结构之中,主要分开了三层 IR,IR 在整个编译器中则起着重要的承上启下作用。从便于开发者编写程序代码的理解到便于硬件机器的理解。

我真的想知道,AI编译器中的IR是什么?的更多相关文章

  1. AI框架中图层IR的分析

    摘要:本文重点分析一下AI框架对IR有什么特殊的需求.业界有什么样的方案以及MindSpore的一些思考. 本文分享自华为云社区<MindSpore技术专栏 | AI框架中图层IR的分析> ...

  2. Xcode4.4(LLVM4.0编译器)中NSArray, NSDictionary, NSNumber优化写法

    Xcode4.4(LLVM4.0编译器)中NSArray, NSDictionary, NSNumber优化写法 从xcode4.4开始,LLVM4.0编译器为Objective-C添加一些新的特性. ...

  3. VS编译器中设置 输出窗口 只显示error,不显示warning 要如何配置

    VS编译器中设置 输出窗口 只显示error,不显示warning 要如何配置 在编译大型项目的时候,总是VS编译器的输出窗口总是会出现一堆warning警告,要想在里面找到error错误,要使用鼠标 ...

  4. 【AI编译器原理】系列来啦!我们要从入门到放弃!

    随着深度学习的应用场景的不断泛化,深度学习计算任务也需要部署在不同的计算设备和硬件架构上:同时,实际部署或训练场景对性能往往也有着更为激进的要求,例如针对硬件特点定制计算代码. 这些需求在通用的AI框 ...

  5. 你真的了解try{ return }finally{}中的return?

    你真的了解try{ return }finally{}中的return?   今天去逛论坛 时发现了一个很有趣的问题: 谁能给我我解释一下这段程序的结果为什么是:2.而不是:3 代码如下: class ...

  6. 眼见为实(1):C++基本概念在编译器中的实现

    眼见为实(1):C++基本概念在编译器中的实现 对于C++对象模型,相信很多程序员都耳熟能详. 本文试图通过一个简单的例子演示一些C++基本概念在编译器中的实现,以期达到眼见为实的效果. 本文的演示程 ...

  7. fatal error c1001 编译器中发生内部错误 OpenMesh6.3

    Internal Compiler Error VS 2015 Update1 VS2015 Update1 编译OpenMesh的额代码时发生错误 fatal error c1001 编译器中发生内 ...

  8. 怎么查看CI,codeigniter的版本信息?想看某个项目中使用的CI具体是哪个版本,怎么查看?

    怎么查看CI的版本信息?想看某个项目中使用的CI具体是哪个版本,怎么查看?system\core\codeigniter.php中可以查看版本常量/** * CodeIgniter Version * ...

  9. 关于gcc编译器中函数不用进行原型声明的解释

    经过大量实验和参考网上的说法得出一个结论: gcc编译器中,函数可以不用提前进行原型声明,编译器会把函数调用同时认为是声明.需要注意的是,由于函数调用的时候并没有写明函数返回值,这是gcc把调用当成声 ...

  10. 条目六《当心C++编译器中最烦人的分析机制》

    当心C++编译器中最烦人的分析机制 C++是较为底层的面相对象语言,在底层的语法规则分析中,有很多隐藏的分析机制. C++中的普遍规律相符,即尽可能地解释为函数声明. 把形式参数的声明用括号括起来是非 ...

随机推荐

  1. 关于spring嵌套事务,我发现网上好多热门文章持续性地以讹传讹

    事情起因是,摸鱼的时候在某平台刷到一篇spring事务相关的博文,文章最后贴了一张图.里面关于嵌套事务的表述明显是错误的. 更奇怪的是,这张图有点印象.在必应搜索关键词PROPAGATION_NEST ...

  2. JVM有意思的图-持续更新

    放一些JVM有意思的图 通过一行代码联想JVM:

  3. maven下载和配置信息

    1. 下载maven: https://maven.apache.org/ 2. 进入官网点击 Download 3. 最新版直接下载 .tar.gz 格式linux系统 .zip windows系统 ...

  4. 深度学习--LSTM网络、使用方法、实战情感分类问题

    深度学习--LSTM网络.使用方法.实战情感分类问题 1.LSTM基础 长短期记忆网络(Long Short-Term Memory,简称LSTM),是RNN的一种,为了解决RNN存在长期依赖问题而设 ...

  5. Python_16 配置文件与封装

    一.查缺补漏 1. ctrl + alt +L 规范格式 2. Python 使用 ini&yaml 配置文件 http://testingpai.com/article/1621245437 ...

  6. Prism Sample 9 ChangeConvention

    上个例子跳过了ViewModelLocator,因是采用约定的方式最为方便. 如果有人要修改约定,自定义view和viewModel的默认自动定位方式,怎么办呢? 在app.xaml.cs重写以下方法 ...

  7. 知乎问题:如何说服技术老大用 Redis ?

    这个问题很微妙,可能这位同学内心深处,觉得 Redis 是所有应用缓存的标配. 缓存的世界很广阔,对于应用系统来讲,我们经常将缓存划分为本地缓存和分布式缓存. 本地缓存 :应用中的缓存组件,缓存组件和 ...

  8. React项目build

    1.项目根目录下新建app.js文件 // 使用 express 搭建一个服务器 const express = require("express"); const { creat ...

  9. 2022-09-19:给定字符串 S and T,找出 S 中最短的(连续)子串 W ,使得 T 是 W 的 子序列 。 如果 S 中没有窗口可以包含 T 中的所有字符,返回空字符串 ““。 如果有不

    2022-09-19:给定字符串 S and T,找出 S 中最短的(连续)子串 W ,使得 T 是 W 的 子序列 . 如果 S 中没有窗口可以包含 T 中的所有字符,返回空字符串 "&q ...

  10. Element-DatePicker的宽度

    Element如何修改DatePicker的宽度 方法/步骤 1 打开一个vue文件,添加DatePicker日期选择器组件,设置默认日期为null.如图 2 在组件上添加style样式属性,设置wi ...