第6章 HSA排队模型

本文详细介绍了HSA(High-PerformanceComputingArchitecture)系统中的队列机制,包括队列的异步框架、用户队列模式、体系结构排队语言AQL以及数据包的提交和调度过程。讨论了内核调度、代理调度的不同,并强调了AQL在描述内核命令中的作用和数据包处理器在执行中的关键角色。
摘要由CSDN通过智能技术生成

6.1 引言

本章了解如何将这些内核分派或提交给HSA系统执行。这是HSA队列的工作。HSA队列是一个异步框架,用于构建潜在从属内核的图表,以便在特定的HSA代理上执行。可以为HSA系统内的单个代理或多个代理创建多个队列。内核之间的依赖关系由HSA信号控制。信号代表了所有HSA系统提供的通用解决方案,并支持不同代理之间的低延迟同步和异步通信。

为了实现低延迟调度,队列由HSA运行时分配。从那时起,应用程序以体系结构排队语言AQL数据包的形式将工作直接提交给队列。API提供了一些控制队列结构的操作,可以通过各种实现方式进行移植。队列调度与HSA运行时分离,并由相应的代理程序包处理器PP管理。数据包处理器协调特定HSA代理上内核的调度。它从一组队列中读取数据包,检查依赖性,并在资源可用时调度相应代理的计算单元上的作业。

6.2 用户队列模式

队列与参数代理描述的单个HSA代理相关联,参数代理可以是支持内核调度或代理调度的代理,也可以是支持二者的调度。支持内核调度的代理能够支持执行从HSAIL编译,或至少匹配HSAIL ABI和执行模型。相反,代理调度队列支持对该设备执行“本机”功能,并且不需要遵循HSAIL并行执行模型。

尽管上图显示了相应代理中的两个队列,但这只是一个逻辑关系,并没有要求将队列内存放置在代理内存中。相反,HSA要求这个内存公开在进程的虚拟地址空间内,并且可以被代理的包处理器访问。包处理器也被显示在其相应的代理中,不过也没明确要求这种情况。包处理器设计有二:
        1. 软件实现:通过低级驱动程序调用,将工作分派到底层设备上。
        2. 硬件实现:在设备的硬件部件上,独立于主机CPU来处理队列调度。HSA在OpenCL2.0实现的基础。支持带有细粒度原子的SVM。

需要注意的是,允许使用硬件直接实现的数据包处理器具有HSA实现的潜力,这导致OpenCL和传统驱动程序的软件驱动程序复杂度降低。

队列的大小表示在任何给定时间可以包含在队列中的最大数据包数量。将队列限制为只有一个生产者,从而允许生产者再向队列添加数据包时避免(有时)使用昂贵的内存一致性操作,如下所述:
        1. 参数“回调”允许应用程序异步接收有关队列相关事件的信息。HSA运行时将3个参数传给回调函数:标识触发调用的事件的代码、指向发生事件的队列的指针以及应用程序数据。每次调用data参数都会传递给回调函数。

因为作业队列通常是有用的,所以HSA提供了创建“软”队列的能力,使得应用程序能够使用开发人员选择的自定义数据包处理方法来实现HSA样式队列。软队列允许与HSA运行时的其他部分无缝集成,特别是HSA信号。

6.3 体系结构排队语言AQL

AQL是一个二进制接口,用于描述内核调度等命令。AQL数据包是一个内存区域,包含用编码单个命令的特定格式编排的数据。HSA运行时不提供创建、销毁或操纵AQL数据包的任何特定功能。这留给更高级别的库或应用程序来直接实现。不需要应用程序为数据包显示保存存储空间,因为队列已经包含表示一系列AQL数据包的缓冲区。

屏障位表示在队列中的较早数据包与该数据包之间是否存在隐式依赖关系。获取和释放栅栏确定内存栅栏,按照HSA内存模型,它的相应范围应该由数据包处理器分别在执行数据包之前或之后执行。在内核执行前后,仔细使用内存栅栏可以减少不必要的内存流量,同时提供从外部控制器(即内核或一组内核之外)对内存可见性的细粒度控制。

数据包类型:
        1. 供应商特定的数据包:布局不能被认为是可移植的。
        2. 无效数据包:指432位容器的内容未定义。将数据包设置为无效状态从消费者向生产者传达该插槽是空闲的。将其从无效状态改变位其他状态,从生产者到消费者通知包已准备好消耗。
        3. 内核调度包:任何HSA代理都必须支持HSAIL ABI及其相应的执行模式。其中包含运行特定内核所需状态的完整规范,包括网格和工作组的维度、维度的数量、内核对象的地址、对包含参数的内存段的应用以及私有和组内存段的大小。此外,还有一个完成信号的句柄,用于报告内核的完成情况。

        4. 代理调度包:使用HSA队列协调执行工作的能力是一种强大的能力。因此,HSA通过软队列和代理调度将其功能公开给应用程序本身。代理调度使应用程序能够位特定代理启动内置函数。与内核调度不同,没有引用包含要执行的代码的内核对象,而是使用一组整数ID来唯一标识与给定代理相关的函数。

        5. 屏障--AND/OR包:屏障包允许应用程序在一组或多组信号上表达依赖关系。任何给定屏障包的信号数量最大限制为5。屏障包可以取决于其他屏障包,因此可以间接指定对更多信号的依赖性。当前存在两种类型的屏障包:AND和OR。它们分别强制向所有信号发出信号通知,或者在屏障包完成前只有一个信号包。

6.3.2 创建数据包

构建数据包的任务留给了应用程序,该应用程序将负责管理分配、初始化和将数据包提交给队列。当数据包被构建时,应用程序可以直接管理数据包创建,而不需要调用HSA运行时。

HSA运行时提供预定义的结构、枚举和其他类型,以减轻数据包创建的负担。

6.4 包的提交和调度

数据包处理器提交和调度数据包分为3个阶段:排队、活动和完成。在高层次,这是通过以下步骤捕获的:
        1. 通过递增与队列关联的writeIndex,在关联的队列中分配一个插槽;
        2. 初始化数据包,将数据包标记为无效;
        3. 以预增量writeIndex将数据包复制到队列中;
        4. 将数据包的类型从无效修改为适当的数据包类型;
        5. 通知数据包处理器通过门铃队列的门铃信号添加了一个数据包;
  此外,队列还定义了两个引用队列head和tail位置的属性:
        1. readIndex指定数据包处理器要使用的下一个AQL数据包的ID。
        2. writeIdx指定要分配的下一个AQL数据包插槽的ID。

在分配队列时,应用程序指定数据包是否由多个生产者同时提交,例如来自多个CPU线程或多个HSA代理,或者只由一个生产者提交。这个选择对将数据包提交给队列的算法有影响。这也意味着数据包处理器如何考虑数据包的调度。

向一个队列提交数据包,支持多个并发生产者的例子。它遵循与之前的实力代码相同的流程,但是现在补充了缺失的代码来处理将数据包写入缓冲区中兵“敲打”数据包处理器的门铃。该功能需要一个队列、一个被设置为无效格式的数据包以及最后一个数据包的格式类型。请记住,在其他“执行”代理可见之前避免设置有效的格式。

将AQL数据包提交给HSA队列,转而谈到数据包的使用和执行的语义。这是数据包处理器的工作。对于HSA代理和实现定义的代理,支持“硬”队列,数据包处理器是一个抽象的执行单元,符合HSA内存模型,并调度相应代理上的数据包。通常,通过“软”队列,应用程序可以实现自己的数据包处理器。

数据包调度器由两个嵌套循环组成。外部循环一直运行,直到调度程序终止,而内部循环则处理来自队列的数据包,而其他部分则保留。如果队列变空,则内部循环退出,调度程序循环等待队列的门铃,希望在更多的工作准备好被消耗之前不要再被唤醒。

在进入内部循环时,调度程序试图从队列中弹出一个数据包,如果成功,该操作返回一个指向数据包缓冲区中相应地址的指针。否则,它返回nullptr,调度程序退出内部循环。在成功的情况下,测试数据包格式以确保适当的动作。如果数据包有效,则控制流程将传递到锁请求的任务的代码。如果数据包被标记为无效,那么这意味着特定数据包正在被写入,并且调度器必须通过继续循环等待它完成。

一旦数据包被成功处理(执行),应用任何释放栅栏。如果完成信号不是nullptr,则通过递减该值来发信号通知。最后,通过将数据包类型设置为无效并递增读索引来释放数据包插槽。

  • 23
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值