AMD KFD的SDMA Packet 类型和定义解析
1. 概述
SDMA(System Direct Memory Access)是AMD GPU架构中的一种高效数据传输机制。SDMA通过一系列结构化的数据包(Packet)实现主机与设备间的内存操作、同步、信号等功能。本文档分析了SDMA Packet类型及其结构体实现,便于开发者理解和扩展SDMA相关功能。
2. SDMA Packet 类型
SDMA Packet通过op(操作码)和sub_op(子操作码)字段区分不同类型。主要类型如下:
| 类型 | 操作码 (op) | 说明 |
|---|---|---|
| NOP | 0 | 空操作,无实际功能 |
| COPY_LINEAR | 1 | 线性内存拷贝 |
| WRITE_UNTILED | 2 | 向线性地址写入数据 |
| FENCE | 5 | 内存屏障/同步 |
| TRAP | 6 | 触发中断或信号 |
| POLL_REGMEM | 8 | 轮询寄存器或内存 |
| CONST_FILL | 11 | 常量填充内存 |
| TIMESTAMP | 13 | 写入时间戳 |
3. 结构体定义详解
下面代码中的union表示一些位字段,具体的我没有写上。本文先理解packet的种类和功能。后面具体分析各union的组成。
3.1 SDMA_PKT_COPY_LINEAR
用于实现线性内存拷贝,支持源/目标地址、拷贝长度、访问属性等配置。
typedef struct SDMA_PKT_COPY_LINEAR_TAG {union { ... } HEADER_UNION; // op, sub_op, 广播等union { ... } COUNT_UNION; // 拷贝字节数union { ... } PARAMETER_UNION; // 访问属性、scope等union { ... } SRC_ADDR_LO_UNION; // 源地址低32位union { ... } SRC_ADDR_HI_UNION; // 源地址高32位struct { ... } DST_ADDR[0]; // 目标地址低/高32位
} SDMA_PKT_COPY_LINEAR;3.2 SDMA_PKT_WRITE_UNTILED
用于向线性地址写入数据,支持TMZ(加密)、scope、mtype等属性。
typedef struct SDMA_PKT_WRITE_UNTILED_TAG {union { ... } HEADER_UNION; // op, sub_op, tmz等union { ... } DST_ADDR_LO_UNION; // 目标地址低32位union { ... } DST_ADDR_HI_UNION; // 目标地址高32位union { ... } DW_3_UNION; // 数据长度、属性union { ... } DATA0_UNION; // 写入数据
} SDMA_PKT_WRITE_UNTILED;3.3 SDMA_PKT_FENCE
用于实现内存屏障,保证数据一致性,支持scope、mtype等属性。
typedef struct SDMA_PKT_FENCE_TAG {union { ... } HEADER_UNION; // op, sub_op, mtype, scope等union { ... } ADDR_LO_UNION; // 屏障地址低32位union { ... } ADDR_HI_UNION; // 屏障地址高32位union { ... } DATA_UNION; // 屏障数据
} SDMA_PKT_FENCE;3.4 SDMA_PKT_CONSTANT_FILL
用于将常量填充到指定内存区域,支持填充大小、属性等。
typedef struct SDMA_PKT_CONSTANT_FILL_TAG {union { ... } HEADER_UNION; // op, sub_op, fillsize等union { ... } DST_ADDR_LO_UNION; // 目标地址低32位union { ... } DST_ADDR_HI_UNION; // 目标地址高32位union { ... } DATA_UNION; // 填充值union { ... } COUNT_UNION; // 填充长度
} SDMA_PKT_CONSTANT_FILL;3.5 SDMA_PKT_TRAP
用于触发中断或信号,常用于任务完成通知。
typedef struct SDMA_PKT_TRAP_TAG {union { ... } HEADER_UNION; // op, sub_opunion { ... } INT_CONTEXT_UNION; // 中断上下文
} SDMA_PKT_TRAP;3.6 SDMA_PKT_POLL_REGMEM
用于轮询寄存器或内存,支持条件判断、重试等。
typedef struct SDMA_PKT_POLL_REGMEM_TAG {union { ... } HEADER_UNION; // op, sub_op, func等union { ... } ADDR_LO_UNION; // 轮询地址低32位union { ... } ADDR_HI_UNION; // 轮询地址高32位union { ... } VALUE_UNION; // 比较值union { ... } MASK_UNION; // 比较掩码union { ... } DW5_UNION; // 轮询间隔、重试次数
} SDMA_PKT_POLL_REGMEM;3.7 SDMA_PKT_TIMESTAMP
用于写入时间戳,便于性能分析与同步。
typedef struct SDMA_PKT_TIMESTAMP_TAG {union { ... } HEADER_UNION; // op, sub_opunion { ... } ADDR_LO_UNION; // 时间戳地址低32位union { ... } ADDR_HI_UNION; // 时间戳地址高32位
} SDMA_PKT_TIMESTAMP;3.8 SDMA_PKT_NOP
空操作包,通常用于对齐或占位。
typedef struct SDMA_PKT_NOP_TAG {union { ... } HEADER_UNION; // op, sub_op, countunion { ... } DATA0_UNION; // 占位数据
} SDMA_PKT_NOP;4. 设计特点和应用场景
设计特点:
位域结构:所有Packet均采用位域结构,便于精确控制每一位的含义,节省空间。
联合体封装:通过union实现同一数据的多种访问方式,方便底层驱动直接操作32位数据。
可扩展性:每种Packet结构均预留了保留字段,便于未来扩展新功能。
属性丰富:支持scope、mtype、temp_hint等多种访问属性,满足不同场景需求。
应用场景
高性能数据搬运:COPY_LINEAR、WRITE_UNTILED等用于主机与设备间大规模数据传输。
同步与信号:FENCE、TRAP用于任务同步、事件通知。
内存初始化:CONST_FILL用于快速初始化内存。
性能分析:TIMESTAMP用于记录关键操作时间点。
轮询机制:POLL_REGMEM用于实现异步等待或条件触发。
