news 2026/2/27 8:12:20

10章 数据共享操作 - “Vega“ 7nm Instruction Set ArchitectureReference Guide

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
10章 数据共享操作 - “Vega“ 7nm Instruction Set ArchitectureReference Guide

本地数据共享(LDS)是一种极低延迟、用于临时数据的RAM暂存器,其有效带宽至少比直接、无缓存的全局内存高出一个数量级。它允许工作组内的工作项之间共享数据,并用于保存像素着色器参数插值所需的参数。与只读缓存不同,LDS允许对内存空间进行高速的"写入后读取"复用(聚集/读取/加载和分散/写入/存储操作)。

10.1 概述

下图展示了LDS集成到AMD GPU内存(使用OpenCL)的概念框架。


(图6:高级内存配置)

LDS物理上位于芯片上,紧邻算术逻辑单元(ALU),其速度大约比全局内存快一个数量级(假设没有存储体冲突)。

每个计算单元拥有64 kB内存,分为32个库,每库512个双字。每个存储体是一个256x32的双端口RAM(每个时钟周期可1读1写)。双字按顺序放入各个存储体,但所有存储体可以同时执行存储或加载操作。一个工作组最多可以请求64 kB内存。跨波前的读取操作以瀑布式分四个周期调度。

LDS内存的高带宽不仅得益于其靠近ALU,还因为能同时访问其多个存储体。因此,有可能并发执行32条写入或读取指令,每条指令名义上为32位;扩展指令(如read2/write2)每条可为64位。然而,如果同一时间对同一存储体进行多次访问尝试,就会发生存储体冲突。在这种情况下,对于索引和原子操作,硬件会将这些对同一存储体的并发访问尝试转为串行访问,以防止冲突。这会降低LDS的有效带宽。因此,为了获得最大吞吐量(最佳效率),避免存储体冲突至关重要。了解请求调度和地址映射是实现这一目标的关键。

10.2 内存层次结构中的数据流

下图是内存结构内数据流的概念图。

要将数据从全局内存加载到LDS,需要从全局内存读取数据并放入工作项的寄存器;然后,执行一次到LDS的存储操作。类似地,要将数据存储到全局内存,需要从LDS读取数据放入工作项寄存器,然后再放入全局内存。为了有效利用LDS,算法必须在全局内存和LDS之间传输的数据上执行多次操作。也可以绕过VGPR,直接从内存缓冲区将数据加载到LDS。

LDS原子操作在LDS硬件中执行。(因此,尽管这些操作不直接使用ALU,但执行此功能会带来LDS延迟。)

10.3 LDS访问

LDS通过以下三种方式之一进行访问:

  • 直接读取

  • 参数读取

  • 索引或原子操作

以下小节描述了这些方法。

10.3.1 LDS直接读取

直接读取仅在LDS中可用,GDS中不可用。

LDS直接读取发生在向量ALU(VALU)指令中,允许LDS提供一个双字值,该值广播到波前中的所有线程,并用作ALU操作的SRC0输入。VALU指令通过在SRC0字段使用LDS_DIRECT来指示输入由LDS提供。

要从LDS读取的数据的LDS地址和数据类型来自M0寄存器:

LDS_addr = M0[15:0] (byte address and must be Dword aligned) DataType = M0[18:16] 0 unsigned byte 1 unsigned short 2 Dword 3 unused 4 signed byte 5 signed short

10.3.2 LDS参数读取

参数读取仅在LDS中可用,GDS中不可用。

像素着色器使用LDS读取顶点参数值;然后像素着色器对其进行插值以找到每个像素的参数值。当使用以下操作码时,会发生LDS参数读取:

  • V_INTERP_P1_F32D = P10 * S + P0 参数插值,第一步。

  • V_INTERP_P2_F32D = P20 * S + D 参数插值,第二步。

  • V_INTERP_MOV_F32D = {P10,P20,P0}[S] 参数加载。

典型的参数插值操作涉及读取三个参数:P0、P10和P20,并使用两个重心坐标I和J来确定最终的每像素值:

Final value = P0 + P10 * I + P20 * J

参数插值指令指示参数属性编号(0到32)和分量编号(0=x, 1=y, 2=z, 3=w)。

参数插值和参数移动指令在使用M0寄存器之前必须初始化它。lds_param_offset[15:0]是从分配给此波前的LDS存储空间起始处到该波前参数在LDS内存中开始位置的地址偏移量。new_prim_mask是一个15位掩码,每个四边形对应一位;该掩码中的"1"表示此四边形开始一个新的图元,"0"表示它使用与前一四边形相同的图元。掩码是15位而非16位,因为波前中的第一个四边形总是开始一个新图元,因此不包含在掩码中。

10.3.3 数据共享的索引和原子访问

LDS和GDS都可以执行索引和原子数据共享操作。为简洁起见,下文使用"LDS",除非特别说明,否则也适用于GDS。

索引和原子操作通过VGPR向LDS提供每个工作项的唯一地址,并将每个工作项的唯一数据提供给VGPR或从VGPR返回。由于LDS内部的分库结构,操作最快可在两个周期内完成,最多可能需要64个周期,具体取决于存储体冲突(映射到同一内存存储体的地址)的数量。

索引操作是简单的LDS加载和存储操作,从VGPR读取数据或将数据返回到VGPR。

原子操作是算术操作,将VGPR的数据与LDS中的数据结合,并将结果写回LDS。原子操作可以选择将LDS的"操作前"值返回到VGPR。

下表列出并简要描述了LDS指令字段。
(表44:LDS指令字段)


所有LDS操作都需要在使用前初始化M0。M0包含一个大小值,可用于将访问限制在分配的LDS范围的子集内。如果不需要限制,则将M0设置为0xFFFFFFFF。

(表45:LDS索引加载/存储)


单地址指令

LDS_Addr = LDS_BASE + VGPR[ADDR] + {InstrOffset1,InstrOffset0}

双地址指令

LDS_Addr0 = LDS_BASE + VGPR[ADDR] + InstrOffset0*ADJ + LDS_Addr1 = LDS_BASE + VGPR[ADDR] + InstrOffset1*ADJ Where ADJ = 4 for 8, 16 and 32-bit data types; and ADJ = 8 for 64-bit.

其中,对于8、16和32位数据类型,ADJ = 4;对于64位数据类型,ADJ = 8。
注意,LDS_ADDR1仅用于READ2、WRITE2和WREXCHG2*。

M0[15:0]提供了此次访问的字节大小。发送到LDS的大小是MIN(M0, LDS_SIZE),其中LDS_SIZE是着色器处理器插值器(SPI)在波前创建时分配的LDS空间量。

地址来自VGPR,ADDR和InstrOffset都是字节地址。

在 wavefront 创建时,LDS_BASE被分配给此波前或工作组拥有的物理LDS区域。

通过将两个偏移量设置为相同的值来指定单个地址。这会导致只发生一次读取或写入,并且仅使用第一个DATA0。

SRC2操作
ds_<op>_src2_<type>操作码是不同的。这些操作数对LDS内存中的两个操作数执行原子操作:一个被视为数据,另一个是第二个源操作数和最终目的地。这些操作的寻址可以根据offset1[7]的最高有效位(MSB)以两种不同的模式运行:
如果为0,则数据项的偏移量由偏移字段作为有符号双字偏移量导出:

LDS_Addr0 = LDS_BASE + VGPR(ADDR) + SIGNEXTEND(InstrOffset1[6:0],InstrOffset0))<<2 // data term LDS_Addr1 = LDS_BASE + VGPR(ADDR) // second source and final destination address

如果该位为1,则数据项的偏移量变为每个线程的偏移量,并且是一个从VGPR为索引读取的MSB导出的有符号双字偏移量。寻址变为:

LDS_Addr0 = LDS_BASE + VGPR(ADDR)[16:0] + SIGNEXTEND(VGPR(ADDR)[31:17])<<2 // data term LDS_Addr1 = LDS_BASE + VGPR(ADDR)[16:0] // second source and final destination address


LDS原子操作
DS_<atomicOp> OP, GDS=0, OFFSET0, OFFSET1, VDST, ADDR, Data0, Data1
数据大小在atomicOp中编码:字节、字、双字或双精度。

LDS_Addr0 = LDS_BASE + VGPR[ADDR] + {InstrOffset1,InstrOffset0}


ADDR是一个双字地址。对于双精度数据,VGPR 0、1和dst是双GPR。VGPR数据源只能是VGPR或常数值,不能是SGPR。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/25 23:06:48

hot100 15.三数之和

一、思路&#xff1a;1.为方便双指针以及跳过相同元素&#xff0c;先把nums排序。2.枚举nums[i]&#xff0c;将问题转化成nums[j] nums[k] -nums[i]&#xff0c;转变成两数之和的问题。3.题目要求答案中不能有重复的三元组&#xff0c;因此要避免重复。&#xff08;1&#xf…

作者头像 李华
网站建设 2026/2/22 9:46:12

本周GitHub九大神级项目推荐,轻松入门大模型技术,错过就是遗憾!

简介 本文精选10个GitHub热门开源项目&#xff0c;涵盖AI大模型应用、文档处理、任务管理等领域。包括腾讯WeKnora知识库框架、AI画流程图工具、agents.md文档标准、Notebook LLM开源替代品、看板工具Fizzy、简历匹配器、AI编程Agent Goose及安全中间件HumanLayer等&#xff0…

作者头像 李华
网站建设 2026/2/22 17:32:40

LobeChat日程安排助手集成日历API

LobeChat日程安排助手集成日历API 在现代办公节奏日益加快的今天&#xff0c;一个会议通知可能刚发出去&#xff0c;下一秒就被十几条消息淹没。用户不得不在聊天工具、邮件和日历应用之间来回切换&#xff0c;手动记录时间、反复确认空闲时段——这种低效的操作模式早已成为数…

作者头像 李华
网站建设 2026/2/20 9:19:00

9、循环迭代与函数构建:脚本编程的核心技巧

循环迭代与函数构建:脚本编程的核心技巧 在脚本编程中,循环和函数是两个非常重要的概念。循环可以帮助我们重复执行特定的任务,而函数则可以将代码模块化,提高代码的复用性和可维护性。下面将详细介绍循环和函数的相关知识。 循环的使用 在脚本编程中,循环是一种非常重…

作者头像 李华
网站建设 2026/2/17 19:57:41

低光图像增强-MSRCP

一、概述在前文我们已经详细说明了SSR单尺度低光图像增强算法了&#xff0c;作为一种传统的低光图像增强算法&#xff0c;SSR只能作为理论学习的算法&#xff0c;帮助我们了解视网膜算法&#xff0c;学习颜色恒常性理论知识&#xff0c;SSR是不足以算真正的图像增强算法的&…

作者头像 李华
网站建设 2026/2/25 4:37:55

青少年运动员慢性踝关节不稳的四周踝关节康复计划

严正声明&#xff1a;本博客内容仅为学习使用&#xff0c;不具备任何医学建议或者参考价值。如有不适&#xff0c;请遵医嘱。本博客所转载之内容&#xff0c;不能作为正式的医学参考&#xff0c;仅供学习 青少年运动员慢性踝关节不稳的四周踝关节康复计划 Four-Week Ankle-Reh…

作者头像 李华