AI编译器的后端优化策略

背景

        工作领域是AI芯片工具链相关,很多相关知识的概念都是跟着项目成长建立起来,但是比较整个技术体系在脑海中都不太系统,比如项目参与中涉及到了很多AI编译器开发相关内容,东西比较零碎,工作中也没有太多时间去做复盘与查漏补缺。但是最近比较闲,发现了一个宝藏级的B站博主,系统的讲了很多AI芯片领域的知识,并把课程资源开源维护,极力推荐大家多多关注。在这里当个搬运工,传播一下。

     

总结

后端优化与前端优化的区别
• 前端优化:输入计算图,关注计算图整体拓扑结构,而不关心算子的具体实现。在 AI 编译器的
前端优化,对算子节点进行融合、消除、化简等操作,使计算图的计算和存储开销最小。
• 后端优化:关注算子节点的内部具体实现,针对具体实现使得性能达到最优。重点关心节点的
输入,输出,内存循环方式和计算的逻辑。 

AI编译器后端部分:

  • 生成低级IR;
  • 后端优化;
  • 代码生成;

1)生成低级IR:不同 AI 编译器内部低级 IR 形式和定义不同,但是对于同一算子,算法的原理
实质相同。对于每个具体的算子,需要用AI编译器底层的接口来定义算法,再由编译器来生成
内部的低级IR。

2)后端优化:针对不同的硬件架构/微架构,不同的算法实现的方式有不同的性能,目的是找
到算子的最优实现方式,达到最优性能。同一算子不同形态如Conv1x1、 Conv3x3、 Conv7x7
都会有不同的循环优化方法。

3)代码生成:对优化后的低级 IR 转化为机器指令执行,现阶段最广泛的借助成熟的编译工具
来实现,非AI 编译器的核心内容。如把低级IR 转化成为 LLVM、NVCC 等成功编译工具的输入
形式,然后调用其生成机器指令。

优化策略

算子概念

算子:深度学习算法由一个个计算单元组成,我们称这些计算单元为算子(Operator,简称Op)。算子是一个函数空间到函数空间上的映射O:X→Y;从广义上讲,对任何函数进行某一项操作都可以认为是一个算子。于AI 框架而言,所开发的算子是网络模型中涉及到的计算函数。

算法:算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。

算子分类:

  • 访存密集型:如 RNN 训练任务,由于 RNN 网络模型结构的计算密度更低,瓶颈转移到host端的 Op Launch 上,因此kernel之间甚至出现了大量空白。对于访存密集型算子部分的工作来说,新硬件带来了更大的性能优化空间。
  • 计算密集型:计算密度是指一个程序在单位访存量下所需的计算量,单位是 FLOPs/Byte,计算密度较大,程序性能受硬件最大计算峰值(下文简称为算力)限制,称为计算密集型程序。

 算子优化的挑战:

  • 优化手段多样:要在不同情况下权衡优化及其对应参数,对于优化专家来说也是相当耗费精力
  • 通用性与移植性:不同类型的硬件架构差异,使得优化方法要考虑的因素也有很大不同
  • 优化间相互影响:各种优化之间可能会相互制约,相互影响。这意味着找到最优的优化方法组合与序列就是一个困难的组合优化问题,甚至是 NP 问题。

算子库:
• 目的:针对访存密集型和计算密集型的算子进行优化。对于一个算子,要实现正确的逻辑计算
或许不难,但要结合硬件能力达到高性能就比较难了,要达到极致的性能更是难上加难。
• 业界一个最为常见的方式是将预置的算子实现封装成计算库。如 CuDNN、CuBLAS、OpenBLA
S、Eigen 这样优秀的计算库。

算子计算与调度

• 计算是算子的定义,回答算子是什么,如何通过具体的算法得到正确的定义结果。
• 调度是算子的执行策略和具体实现,回答系统具体如何执行算子的计算定义。
• 同一算子会有不同的实现方式(即不同的调度方式),但是只会有一种计算形态(具体定义)。
• 计算实现(Function / Expression)和计算在硬件单元上的调度(Schedule)是分离。

        算子调度具体执行的所有可能的调度方式称为调度空间,AI 编译器优化的目的就是为算子提供一种最优的调度,使得算子在硬件上运行时间最优。

循环优化

循环展开Loop Unrolling

• 对循环进行展开,以便每次迭代多次使用加载的值,使得一个时钟周期的流水线上尽可能满负荷计算。在流水线中,会因为指令顺序安排不合理而导致NPU等待空转,影响流水线效率。循环展开为编译器进行指令调度带来了更大的空间。

循环分块 Loop tiling
• 由于内存空间有限,代码访问的数据量过大时,无法一次性将所需要的数据加载到设备内存,
循环分块能有效提高NPU cache 上的访存效率,改善数据局部性。
• 如果分块应用于外部循环,会增加计算的空间和时间局部性;分块应与缓存块一起作用,可以
提高流水线的效率。

• Loop Tiling 的目的是确保一个 Cache 在被用过以后,后面再用的时候其仍然在 cache 中。
实现思路:当一个数组总的数据量无法放在 cache 时,把总数据分成一个个 tile 去访问,令每
个 tile 都可以满足 Cache
具体做法:把一层内层循环分成 outer loop * inner loop。然后把 outer loop 移到更外层去,
从而确保 inner loop 一定能满足 Cache

在我之前写的博文CUDA编程的矩阵乘优化中,有一个优化思想就是循环分块。

循环重排 Loop Reorder
• 内外层循环重排,改善空间局部性,并最大限度地利用引入缓存的数据。对循环进行重新排序,
以最大程度地减少跨步并将访问模式与内存中的数据存储模式对齐

循环融合 Loop Fusion
• 循环融合将相邻或紧密间隔的循环融合在一起,减少的循环开销和增加的计算密度可改善软件
流水线,数据结构的缓存局部性增加。

循环拆分 Loop Split
• 拆分主要是将循环分成多个循环,可以在有条件的循环中使用,分为无条件循环和含条件循环。

指令优化

向量化 Vectorization

SIMD 寄存器先保持vec_sum的值,在reduction 步骤,,vec_sum 再逐个求总和。

张量化 Tensorization

• Volta 架构中,一个SM由8个FP64 Cuda Cores,16个INT32 Cuda Core,16个FP32 Cuda Core,和128个Tensor Core组成,一共有4个SM。

        主流CPU/GPU硬件厂商都提供了专门用于张量化计算的张量指令,如英伟达的张量核指令、
英特尔的VN。利用张量指令的一种方法是调用硬件厂商提供的算子库,如英伟达的cuBLAS和
cuDNN,以及英特尔的oneDNN等。然而,当模型中出现新的算子或需要进一步提高性能时,这种方法的局限性便显露无遗。

1. 新的硬件体系带来了超越向量运算的新指令集,调度必须使用这些指令才能从加速中获益
2. 张量计算基元的输入是多维的,具有固定的或可变的长度,并指示不同的数据布局
3. 新的 AI 加速器正以它们自己的张量指令出现

存储优化

访存延迟 Latency Hiding
• 延迟隐藏(Latency Hiding)是指将内存操作与计算重叠,最大限度地提高内存和计算资源利用
率的过程。

CPU:
• 延迟隐藏可以通过多线程,或者硬件隐式数据预取实现
GPU:
• 依赖于 Wrap Schedule 对多线程的管理调度和上下文切换实现
NPU/TPU:
• 采用解耦访问/执行(Decoupled Access/Execute,DAE)架构

内存分配

        传统编译器通过将内存逻辑划分为不同区段来提供程序员访问内存的权限(栈、堆、静态存储区),而每段空间都有各自的大小,一旦开发者在使用过程中将该大小耗尽,就会出现内存不足错误。
        AI芯片上内存分为:Shared Memory, Local Momory。如下是GPU chip的内存层级示意图:

自动调优

        AI编译器的Ato tuning是指对于给定的程序和目标架构,自动调优算法的方式找到最优的编译优化方法。需要考虑的问题是:使用哪些优化方法?选择什么参数集?用什么顺序应用优化方法以达到最佳性能?

步骤:

1) 参数化 Parameterization
2)成本模型 Cost Model
3)搜索算法 Search Algorithm

参数化 Parameterization:对调度优化问题进行建模,参数化优化空间一般由可参数化变换(Lo
op)的可能参数取值组合构成,因此需要调度原语进行参数化表示。Halide 将算法和调度解耦,
TVM 提供调度模板。

成本模型 Cost Model:用来评价某一参数化下的调度性能,根据对调度额评价来指导最搜索到
最优的调度策略。可以从运行时间、内存占用、编译后指令数来评价。实现方式主要有1)基
于NPU硬件的黑盒模型;2)基于模拟的预定义模型;3)ML-Base 模型,通过机器学习模型来
对调度性能进行预测

搜索算法 Search Algorithm:确定初始化和搜索空间后,在搜索空间找找到达到性能最优的参数
配置。常用的搜索算法有1)遗传算法、2)模拟退火算法、3)强化学习等。

系列:AI编译器的前端优化策略-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/351044.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

算子:详细篇

目录 一、执行环境 1.1 创建执行环境 1.2 执行模式 二、源算子 2.1 从集合中读取数据 2.2 从文件读取数据 2.3 从socket读取数据 2.4 从kafka读取数据 三、转换算子 3.1 基本转换算子 (1)映射(map) (2)过滤(filter) &#xff08…

网络分层和网络原理之UDP和TCP

温故而知新 目录 网络分层 应用层 http协议 传输层 介绍 UDP协议 TCP协议 网络层 数据链路层 物理层 网络分层 一. 应用层 应用程序 现成的应用层协议有超文本协议http(不仅仅有文本). http协议 http://t.csdnimg.cn/e0e8khttp://t.csdnimg.cn/e0e8k 自定义应…

云手机哪一款好用?

随着海外市场的不断发展,云手机市场也呈现蓬勃的态势,众多云设备软件纷纷涌现。企业在选择云手机软件时,如何找到性能卓越的软件成为一项关键任务。在众多选择中,OgPhone云手机凭借其卓越的性能和独特功能脱颖而出。以下是OgPhone…

音频格式之AAC:(3)AAC编解码原理详解

系列文章目录 音频格式的介绍文章系列: 音频编解码格式介绍(1) ADPCM:adpcm编解码原理及其代码实现 音频编解码格式介绍(2) MP3 :音频格式之MP3:(1)MP3封装格式简介 音频编解码格式介绍(2) MP3 :音频格式之MP3&#x…

一文详解C++拷贝构造函数

文章目录 引入一、什么是拷贝构造函数?二、什么情况下使用拷贝构造函数?三、使用拷贝构造函数需要注意什么?四、深拷贝和浅拷贝浅拷贝深拷贝 引入 在现实生活中,可能存在一个与你一样的自己,我们称其为双胞胎。 相当…

5|领域建模实践(上):怎样既准确又深刻地理解业务知识?

上节课咱们完成了事件风暴,梳理了系统的行为需求。但你可能也发现了,其实还有些微妙的业务概念还没有澄清,这就要靠领域建模来完成了。 建立领域模型是 DDD 的核心。要建好领域建模,需要理论和实践相结合。由于我们的模型有一定的…

CSC签证费报销的相关规定及要求-主要国家签证费报销凭据

国家留学基金委(CSC)派出流程很多是在留学服务机构办理,即北京教育部留学服务中心及教育部出国人员上海集训部,其中含签证费报销。本篇知识人网小编以上海集训部为例,详细解读一下签证费报销的相关规定及要求&#xff…

sql 行转列 日周月 图表统计

目录 目录 需求 准备 月 分析 按月分组 行转列 错误版本 正确版本 日 分析 行转列 周 分析 按周分组 行转列 本年 需求 页面有三个按钮 日周月,统计一周中每天(日),一月中每周(周),一年中每月(月),设备台数 点…

Linux中断 -- 中断路由、优先级、数据和标识

目录 1.中断路由 2.中断优先级 3.中断平衡 4.Linux内核中重要的数据结构 5.中断标识 承前文,本文从中断路由、优先级、数据结构和标识意义等方面对Linux内核中断进行一步的解析。 1.中断路由 Aset affinity flow GIC文中有提到SPI类型中断的路由控制器寄存器为…

Leetcode—114. 二叉树展开为链表【中等】

2023每日刷题(九十八) Leetcode—114. 二叉树展开为链表 Morris-like算法思想 可以发现展开的顺序其实就是二叉树的先序遍历。算法和 94 题中序遍历的 Morris 算法有些神似,我们需要两步完成这道题。 将左子树插入到右子树的地方将原来的右…

Java - OpenSSL与国密OpenSSL

文章目录 一、定义 OpenSSL:OpenSSL是一个开放源代码的SSL/TLS协议实现,也是一个功能丰富的加密库,提供了各种主要的加密算法、常用的密钥和证书封装管理功能以及SSL协议。它被广泛应用于Web服务器、电子邮件服务器、VPN等网络应用中&#x…

线性表--栈

1.什么是栈? 栈是一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除 操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出的原则。 压栈:栈的插入操作叫做进栈/压栈/入栈&#xff…

YOLOv5改进 | Conv篇 | 在线重参数化卷积OREPA助力二次创新(提高推理速度 + FPS)

一、本文介绍 本文给大家带来的改进机制是一种重参数化的卷积模块OREPA,这种重参数化模块非常适合用于二次创新,我们可以将其替换网络中的其它卷积模块可以不影响推理速度的同时让模型学习到更多的特征。OREPA是通过在线卷积重参数化(Online Convolutional Re-parameteriza…

TensorFlow2实战-系列教程3:猫狗识别1

🧡💛💚TensorFlow2实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Jupyter Notebook中进行 本篇文章配套的代码资源已经上传 1、项目介绍 基本流程: 数据预处理:图像数据处理&#xff0c…

Spring 的执行流程以及 Bean 的作用域和生命周期

文章目录 Bean 的作用域更改作用域的方式singletonprototype Spring 执行流程Bean 的生命周期 Bean 的作用域 Spring 容器在初始化⼀个 Bean 的实例时,同时会指定该实例的作用域。Bean 有6种作用域 singleton:单例作用域prototype:原型作用域…

Hadoop-MapReduce-MRAppMaster启动篇

一、源码下载 下面是hadoop官方源码下载地址&#xff0c;我下载的是hadoop-3.2.4&#xff0c;那就一起来看下吧 Index of /dist/hadoop/core 二、上下文 在上一篇<Hadoop-MapReduce-源码跟读-客户端篇>中已经将到&#xff1a;作业提交到ResourceManager&#xff0c;那…

首发:2024全球DAO组织发展研究

作者&#xff0c;张群&#xff08;专注DAO及区块链应用研究&#xff0c;赛联区块链教育首席讲师&#xff0c;工信部赛迪特邀资深专家&#xff0c;CSDN认证业界专家&#xff0c;微软认证专家&#xff0c;多家企业区块链产品顾问&#xff09; DAO&#xff08;去中心化自治组织&am…

adb测试冷启动和热启动 Permission Denial解决

先清理日志 adb shell logcat -c 打开手机模拟器中的去哪儿网&#xff0c;然后日志找到包名和MainActivity adb shell logcat |grep Main com.Qunar/com.mqunar.atom.alexhome.ui.activity.MainActivity 把手机模拟器的去哪儿的进程给杀掉 执行 命令 adb shell am start -W…

TensorFlow2实战-系列教程1:回归问题预测

&#x1f9e1;&#x1f49b;&#x1f49a;TensorFlow2实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Jupyter Notebook中进行 本篇文章配套的代码资源已经上传 1、环境测试 import tensorflow as tf import numpy as np tf.__version__打印结果 ‘…

深入理解Redis:如何设置缓存数据的过期时间及其背后的机制

目录 Redis 给缓存数据设置过期时间 Redis是如何判断数据是否过期的呢&#xff1f; 过期的数据的删除策略 Redis 内存淘汰机制 Redis 给缓存数据设置过期时间 一般情况下&#xff0c;我们设置保存的缓存数据的时候都会设置一个过期时间。为什么呢&#xff1f; 因为内存是有…