调度pass的定制

概述

作为调度pass实现类,MachineScheduler 和 PostMachineScheduler 的优点之一是允许开发者在LLVM 已有调度算法和策略基础上做不同的定制化

PostMachineScheduler 类的定制相对简单,主要是MachineSchedStrategy 接口的定制。 MachineScheduler 类的定制化更为复杂,主要包括三个方面: 调度策略定制、MachineSchedStrategy 接口定制和ScheduleDAGMILive 类定制

调度策略定制

MachineScheduler 类仅负责选择要调度的区域。如果目标后端不需要要通过定制MachineSchedStrategy 接口对区域调度做过多定制,而只是希望调整调度策略类GenericScheduler 的某些策略,如定制 MachineScheduler 调度方向、寄存器压力跟踪策略等,可以通过指定调度器的某些高层配置,实现定制调度策略

这些高层配置一般在 overrideSchedPolicy() 函数中指定,以此在子目标层级设定指定调度的配置选项。例如,AMDGPU后端GCN子目标的重写 overrideSchedPolicy() 函数实现代码如下

void GCNSubtarget::overrideSchedPolicy(MachineSchedPolicy &Policy,unsigned NumRegionInstrs) const {// Track register pressure so the scheduler can try to decrease// pressure once register usage is above the threshold defined by// SIRegisterInfo::getRegPressureSetLimit()Policy.ShouldTrackPressure = true;// Enabling both top down and bottom up scheduling seems to give us less// register spills than just using one of these approaches on its own.Policy.OnlyTopDown = false;Policy.OnlyBottomUp = false;// Enabling ShouldTrackLaneMasks crashes the SI Machine Scheduler.if (!enableSIScheduler())Policy.ShouldTrackLaneMasks = true;
}

其中,结构体 MachineSchedPolicy 定义了 MachineSchedStrategy 接口中没有提供的调度策略

  • 例如,MachineSchedPolicy 中的 ShouldTrackPressure 字段表示调度器开启寄存器压力跟踪
  • 一旦寄存器使用量超过SIRegisterInfo::getRegPressureSetLimit() 定义的阀值,调度器可以尝试降低寄存器压力
  • 寄存器分配的指令调度不需要跟踪寄存器压力

MachineSchedPolicy 中 的 OnlyTopDonw 和 OnlyBottomUp 字段分别表示调度强制自顶向下或自底向上调度指令。如果二者都为false,则表示双向调度

GCN 子目标使用了双向调度策略,因为开发者认为这样可以减少寄存器溢出。用户可以通过llc命令行选项-misched-topdown/bottomup 改变默认策略。 MachineSchedPolicy 中的字段ShouldTrackLaneMasks 表示调度器是否跟踪LaneMask

LaneMask 是寄存器的位掩码,通常用于显示组成寄存器的子寄存器的活跃性。跟踪LaneMask有助于对子寄存器的写入操作进行重新排序

MachineSchedStrategy 接口定制

LLVM 中的大多数后端不需要重写DAG构建器和列表调度,但如果某些后端的子目标需要定制调度启发式策略,则可以通过定制 MachineSchedStrategy 接口,并在其中实现自定义调度算法

MachineSchedStrategy 接口需要实现用于跟踪、保存就绪节点的优先级队列,以及操作队列的函数,包括队列中添加节点、从队列中调度节点的操作等

  • 例如:AMDGPU 后端的R600子目标定义了 MachineSchedStrategy 接口类R600SchedStrategy,其实现代码如下:
class R600SchedStrategy final : public MachineSchedStrategy {void initialize(ScheduleDAGMI *dag) override;SUnit *pickNode(bool &IsTopNode) override;void schedNode(SUnit *SU, bool IsTopNode) override;void releaseTopNode(SUnit *SU) override;void releaseBottomNode(SUnit *SU) override;}

MachineSchedStrategy 类中定义了保存就绪节点的队列,以及操作队列的releaseTopNode(),releaseBottomNode() 等函数

上述代码中的pickNode() 函数是指令调度框架的入口函数,其中根据 “AMD Accelerated Paralled Processing OpenCL Programming Guide” 文档的要求实现了R600 的调度策略

  • 如果R600SchedStrategy 类的pickNode() 函数没有选中符合条件的节点,仍可调用GenericScheduler 类的 pickNode() 函数完成调度

上述代码中的 schedNode() 函数在节点被调度后被调用,可用于更新调度器的内部状态,如已发射指令计数等

R600 子目标可以在调用 createMachineScheduler() 函数为标准 MachineScheduler 调度 pass 生成 ScheduleDAGInstrs 实例时,在 ScheduleDAGILive 实例中 插入自定义 MachineSchedStrategy 接口 R600SchedStrategy, 以此决定调度节点方式

class R600PassConfig final : public AMDGPUPassConfig {
public:R600PassConfig(LLVMTargetMachine &TM, PassManagerBase &PM): AMDGPUPassConfig(TM, PM) {}ScheduleDAGInstrs *createMachineScheduler(MachineSchedContext *C) const override {return createR600MachineScheduler(C);}bool addPreISel() override;bool addInstSelector() override;void addPreRegAlloc() override;void addPreSched2() override;void addPreEmitPass() override;
};

上述通过重写 MachineSchedStrategy 接口的方法实现自定义调度算法的工作量较大。如果希望仅对 GenericScheduler 类中已有的启发式策略做调整,但复用大部分调度框架基础设施,则可以由GenericScheduler 类派生自定义子类,在其中添加定制调度策略,实现某些GenericScheduler 类中未定义的架构行为

  • 例如,AMDGPU 后端的GCN 子目标定义了自己的 MachineSchedStrateg 派生类GCNMaxOccupancySchedStrategy。
  • CGNMAxOccpancySchedStrategy 类与GenericScheduler 不同之处在于,GCNMaxOccupancySchedStrategy 类使用不同的启发式策略确定寄存器超额(excess) 和 临界(critical) 压力,其目标是最大化内核占用率,即最大化每个SIMD的最大wavefront 数

与R600 子目标实现方式类似,GCN子目标的 createMachineScheduler() 函数通过调用 createGCNMaxOccupancyMachineScheduler() 函数,在生成GCNScheduleDAGMILive实例时插入自定义 GCNMaxOccupancySchedStrategy接口

/// Instantiate a ScheduleDAGInstrs that will be owned by the caller.
ScheduleDAGInstrs *MachineScheduler::createMachineScheduler() {// Select the scheduler, or set the default.MachineSchedRegistry::ScheduleDAGCtor Ctor = MachineSchedOpt;if (Ctor != useDefaultMachineSched)return Ctor(this);// Get the default scheduler set by the target for this function.ScheduleDAGInstrs *Scheduler = PassConfig->createMachineScheduler(this);if (Scheduler)return Scheduler;// Default to GenericScheduler.return createGenericSchedLive(this);
}/// Create the standard converging machine scheduler. This will be used as the
/// default scheduler if the target does not set a default.
ScheduleDAGMILive *llvm::createGenericSchedLive(MachineSchedContext *C) {ScheduleDAGMILive *DAG =new ScheduleDAGMILive(C, std::make_unique<GenericScheduler>(C));// Register DAG post-processors.//// FIXME: extend the mutation API to allow earlier mutations to instantiate// data and pass it to later mutations. Have a single mutation that gathers// the interesting nodes in one pass.DAG->addMutation(createCopyConstrainDAGMutation(DAG->TII, DAG->TRI));return DAG;
}

createGenericSchedLive() 函数中调用了函数 addMutation(),其目的是在 DAG 构造器中增加一些后处理步骤,这些后处理步骤以ScheduleDAGMuation 对象的作用是在调度前根据硬件目标相关知识,向数据依赖图中添加TableGen语言不能表达的调度约束,即通过在数据依赖图中增加边调整图中的依赖关系,其代价是降低了调度的灵活性

上述代码中添加了三个ScheduleDAGMuation对象,这三个对象按照其添加的顺序,依次在正常DAG构造后作用于DAG

ScheduleDAGMILive 类定制

通常,定制目标后端的MachineSchedStrategy 接口就应该足以实现新的调度算法。不过,目标后端调度程序可以通过进一步派生自己的ScheduleDAGMILive 子类试想调度器,并重载其schedule() 虚函数,实现任何后端特定的调度处理. 例如,AMDGPU 后端的GCN子目标定义了自己的 ScheduleDAGMILive派生类 GCNScheduleDAGMILive,定义如下:

class GCNScheduleDAGMILive final : public ScheduleDAGMILive {void schedule() override;void finalizeSchedule() override;
}

finalizeSchedule() 函数允许目标后端在MachineFunction 级别执行最终的调度操作,即遍历所有的区域,通过寄存器压力监视器RPTracker计算区域的寄存器压力,然后调用 schedule()

GCNScheduleDAGMILive::schedule() 函数实现了 ScheduleDAGInstrs 调度指令序列接口,并通过上述GCNMaxOccupancySchedStrategy 调度策略接口,完成GCN子目标特定的调度处理。

ScheduleDAGMILive::schedule() 函数通过调度策略实现类对象 SchedImpl,调用GCNMaxOccpuancySchedStrategy类的 pickNode() 函数选择调度节点

此外,还可以通过GCNMaxOccupancySchedStrategy 调度策略接口判断寄存器压力是否超过限制


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【算法】Dijkstra算法

戴克斯特拉算法(Dijkstras Algorithm),由荷兰杰出计算机科学家艾兹赫尔戴克斯特拉设计,是解决非负权有向图中单源最短路径问题的经典算法。它构建了一个逐步扩展的最短路径树,从指定的源点出发,逐步探索并确定到图中所有其他顶点的最短路径。这一算法在网络路由选择、地理…

C语言旋转动画

目录 开头程序程序的流程图C语言旋转动画(程序的效果)结尾 开头 大家好&#xff0c;我叫这是我58。在这里&#xff0c;我们要来看我用C语言编译成的可以顺时针或者逆时针旋转的动画相关的一些东西和那个动画的顺时针与逆时针的版本。 程序 #define _CRT_SECURE_NO_WARNINGS …

Hospital Management System v4.0 SQL 注入漏洞(CVE-2022-24263)

前言 CVE-2022-24263 是一个影响 Hospital Management System (HMS) v4.0 的 SQL 注入漏洞。这个漏洞允许攻击者通过注入恶意 SQL 代码来获取数据库的敏感信息&#xff0c;甚至可能控制整个数据库。以下是对这个漏洞的详细介绍&#xff1a; 漏洞描述 在 Hospital Management…

【MindSpore学习打卡】应用实践-自然语言处理-深入理解LSTM+CRF在序列标注中的应用

在自然语言处理(NLP)领域&#xff0c;序列标注是一项重要的任务。其目标是为给定的输入序列中的每个Token分配一个标签。序列标注的应用范围广泛&#xff0c;包括分词、词性标注、命名实体识别(NER)等。在本文中&#xff0c;我们将探讨如何利用LSTM和CRF模型进行序列标注&#…

无人机之穿越机知识篇

一、定义和类型 穿越机&#xff0c;即FPV Drone或Racing Drone&#xff0c;是一种主要通过第一人称视角&#xff08;FPV&#xff09;进行操作的无人机。这种无人机通常配备有四个电机和相应的飞控系统&#xff0c;使其具有极高的飞行自由度和速度。穿越机主要分为竞速型和花飞…

electron在VSCode和IDEA及webStrom等编辑器控制台打印日志乱码

window10环境下设置 1.打开Windows设置 2.打开时间和语言&#xff0c;选择语言菜单、如何点击管理语言设置 3.打开之后选择管理&#xff0c;选择更改系统区域设置&#xff0c;把Beta版&#xff1a;使用Unicode UTF-8提供全球语言支持 勾上&#xff0c;点击确定&#xff0c;…

C# —— try catch

代码出现错误的两种情况 编译错误: 编译不通过&#xff0c;只要是编译不通过 铁定执行不了&#xff0c;例如出现语法错误(少符号、中英文错误 爆红); 运行时候的错误: 程序在运行的期间出现的逻辑错误&#xff0c;例如(数组越界了 格式转换错误等) 异常代码: 例如除数如…

甄选范文“论区块链技术及应用”,软考高级论文,系统架构设计师论文

论文真题 区块链作为一种分布式记账技术,目前已经被应用到了资产管理、物联网、医疗管理、政务监管等多个领域。从网络层面来讲,区块链是一个对等网络(Peer to Peer, P2P),网络中的节点地位对等,每个节点都保存完整的账本数据,系统的运行不依赖中心化节点,因此避免了中…

Oracle的wrap工具怎么用

Oracle的Wrap工具是一个用于加密PL/SQL代码&#xff08;如存储过程、函数、包等&#xff09;的工具。使用Wrap工具加密后的代码变得难以阅读&#xff0c;但Oracle数据库仍然能够执行这些加密后的代码。以下是Oracle Wrap工具的基本使用方法&#xff1a; 一、准备工作 确认Wra…

什么样的视频才算得上优质视频

首先&#xff0c;让我们谈谈制作优质广告视频的好处。优质广告视频不仅能获得流量激励&#xff0c;还能提升广告竞价的胜率。此外&#xff0c;它们还能在专属流量池中获得更多曝光机会。如果我们的优质素材占比高&#xff0c;还能加快广告的审核速度。听起来&#xff0c;这确实…

MySQL 9.0 新功能概览

官方文档 https://dev.mysql.com/doc/refman/9.0/en/mysql-nutshell.html 时隔 6 年多&#xff0c;上周 Oracle 发布了 MySQL 最新的大版本 9.0。我们一起来看看新版本有哪些东西。 用 JavaScript 写存储过程 半年前已经单独介绍过 「虽迟但到&#xff01;MySQL 可以用 Java…

微软Edge浏览器基本解析

微软Edge浏览器是微软公司开发的一款现代网页浏览器&#xff0c;它是Windows操作系统的默认浏览器&#xff0c;旨在取代旧版的Internet Explorer浏览器。以下是关于微软Edge浏览器的全解析&#xff1a; 一、历史背景 微软Edge浏览器最早于2015年随Windows 10一起发布&#xf…

应用数学与机器学习基础 - 数值计算之线性最小二乘实例篇

序言 线性最小二乘法&#xff0c;作为统计学与数据科学中的基石之一&#xff0c;自其诞生以来便在科学研究、工程技术、经济预测等众多领域展现出了强大的应用价值。这一方法的核心思想在于&#xff0c;通过最小化误差的平方和来寻找数据的最佳函数匹配&#xff0c;即找到一个…

方圆资源网,方圆资源官网

在当今这个信息化高速发展的时代&#xff0c;方圆资源网络已成为推动社会进步、促进经济发展的重要力量。方圆资源网不仅汇聚了海量的信息资源&#xff0c;更为我们提供了一个高效、便捷的信息交流平台。本文旨在详细介绍资源网的概念、特点、功能以及其在现代社会中的重要意义…

移动端Vant-list的二次封装,查询参数重置

Vant-list的二次封装 场景&#xff1a;在写项目需求的时候&#xff0c;移动端有用到vant-list组件。后续需求更新说要对列表数据页加搜索和筛选的功能。发现每次筛选完得在页面内手动重置一次查询参数。不方便&#xff0c;所以封了一层。 二次封装代码 <template><…

DeepMind的JEST技术:AI训练速度提升13倍,能效增强10倍,引领绿色AI革命

谷歌旗下的人工智能研究实验室DeepMind发布了一项关于人工智能模型训练的新研究成果&#xff0c;声称其新提出的“联合示例选择”&#xff08;Joint Example Selection&#xff0c;简称JEST&#xff09;技术能够极大地提高训练速度和能源效率&#xff0c;相比其他方法&#xff…

华为乾崑智驾加持:深蓝S07首次亮相

最近&#xff0c;特斯拉FSD即将入华的消息&#xff0c;让智能驾驶成为了汽车行业热议的焦点&#xff0c;而当新能源汽车的代表企业深蓝汽车&#xff0c;与全球领先的华为乾崑智驾强强联手&#xff0c;一场颠覆性的智能出行变革也已蓄势待发。 7月8日&#xff0c;深蓝汽车携其最…

vue process.env.VUE_APP_BASE_API的相关配置及axios简单封装

1、根目录底下新建.env.dev和env.prod,内容如下&#xff1a; VUE_APP_BASE_API http://192.168.1.xx:xxx2、vue.config相关内容&#xff1a; devServer: {hot: true, //热加载host: 0.0.0.0,port: 8080, //端口// https: false, //false关闭https&#xff0c;true为开启// op…

[数仓]四、离线数仓(Hive数仓系统-续)

第8章 数仓搭建-DWT层 8.1 访客主题 1)建表语句 DROP TABLE IF EXISTS dwt_visitor_topic; CREATE EXTERNAL TABLE dwt_visitor_topic (`mid_id` STRING COMMENT 设备id,`brand` STRING COMMENT 手机品牌,`model` STRING COMMENT 手机型号,`channel` ARRAY<STRING> C…

MinIO - 服务端签名直传(前端 + 后端 + 效果演示)

目录 开始 服务端签名直传概述 代码实现 后端实现 前端实现 效果演示 开始 服务端签名直传概述 传统的&#xff0c;我们有两种方式将图片上传到 OSS&#xff1a; a&#xff09;前端请求 -> 后端服务器 -> OSS 好处&#xff1a;在服务端上传&#xff0c;更加安全…