随着深度学习的不断发展,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. 数据分析04-pandas(apply函数、排序、数据合、分组聚合、透视表、交叉表及项目分析)

    数据分析-04 排序 按标签(行)排序 按标签(列)排序 按某列值排序 数据合并 concat merge & join 分组聚合 分组 聚合 透视表与交叉表 透视表 交叉表 项目:分析影响学 ...

  2. #PowerBi 10分钟学会,以X为结尾的聚合函数

    前言 在Power BI中,我们经常需要对数据进行聚合计算,比如求和.求平均.求最大值等. Power BI提供了一系列的聚合函数,可以用来对表中列的值进行聚合然后返回一个值.这些函数通常只需要一个参 ...

  3. Centos环境下部分中间件“rabbitmq、rocketmq、clickhouse”部署

    部分中间件部署 目录 部分中间件部署 docker部署rabbitmq docker部署rocketmq 单机部署clickhouse docker部署rabbitmq # 拉镜像 docker pu ...

  4. EasyExcel自适应列宽

    import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.Head; import com. ...

  5. .NET6 + EF Core + MySQL 创建实体和数据库、EFCore 数据迁移

    前言 接上期文章<.NET6项目连接数据库方式方法>,有人问了我几个问题,现在就这几个问题,拓展延申一下创建实体类.数据库.把ORM框架和数据迁移都写进去. 安装ORM框架,这里我们采用E ...

  6. 代码随想录算法训练营Day49 动态规划

    代码随想录算法训练营 代码随想录算法训练营Day49 动态规划|  121. 买卖股票的最佳时机 122.买卖股票的最佳时机II 121. 买卖股票的最佳时机 题目链接:121. 买卖股票的最佳时机 ...

  7. ENVI指定像元数量(行数与列数)裁剪栅格图像

      本文介绍基于ENVI软件,实现栅格遥感影像按照像元行列号与个数进行指定矩形区域裁剪的方法.   一般的,如果我们需要裁剪某个具体的行政区域,按照对应区域的矢量图层裁剪即可:如果需要裁剪某个大致的区 ...

  8. C2简介

    C2简介 学习命令与控制的基本知识,帮助您成为更好的红队队员并简化您的下一次红队评估! thm:https://tryhackme.com/room/introtoc2 介绍 命令与控制 ( C2 ) ...

  9. Hive执行计划之一文读懂Hive执行计划

    目录 概述 1.hive执行计划的查看 2.学会查看Hive执行计划的基本信息 3.执行计划步骤操作过程 4.explain extended 概述 Hive的执行计划描述了一个hiveSQL语句的具 ...

  10. rust cargo build一直出现 Blocking waiting for file lock on package cache

    如果确定没有多个程序占用,可以删除rm -rf ~/.cargo/.package-cache,然后再执行