AMD KFD驱动分析系列0:HSA(异构系统架构)驱动概览
1. 引言
随着异构计算的普及,GPU已成为高性能计算、人工智能等领域不可或缺的算力资源。AMD ROCm平台通过HSA(Heterogeneous System Architecture)标准,打通了CPU与GPU的协作壁垒。KFD(Kernel Fusion Driver)作为AMD GPU的内核驱动,承担着设备管理、内存分配、任务调度、事件同步等核心职责。而libhsakmt库则作为KFD的用户态“thunk”库,向上层HSA Runtime和应用程序提供了统一、易用的API接口,极大简化了用户与底层硬件的交互复杂度。
本文将围绕libhsakmt的核心功能,结合源码结构与典型应用场景,系统阐述其在设备实例管理、内存管理、任务调度、事件同步、数据传输等方面的组件。
2. HSA与KFD驱动架构概览
2.1 HSA架构简介
HSA(异构系统架构)是一套开放标准,旨在实现CPU、GPU等多种处理器的高效协作。其核心思想是通过统一的内存模型、任务调度和同步机制,消除传统CPU-GPU编程中的数据拷贝和同步瓶颈。
2.2 KFD驱动的作用
KFD(Kernel Fusion Driver)是AMD ROCm平台的内核模块,主要负责:
GPU设备的发现与管理
进程与设备上下文的建立
显存与共享内存的分配与回收
任务队列的调度与执行
事件与信号的同步与通知
主机与设备间的数据传输
KFD通过字符设备(如/dev/kfd
)向用户空间暴露接口,用户空间库(如libhsakmt)通过ioctl等机制与KFD通信。
2.3 libhsakmt的定位
libhsakmt作为KFD的用户态支撑库,承担着以下职责:
封装KFD的ioctl调用,向上层提供C API
管理设备实例、内存、队列、事件等资源
维护进程与线程安全
屏蔽不同硬件与内核版本的差异
提供调试、性能计数等扩展功能
熟悉图形驱动的朋友,libhsakmt在软件栈中的位置就是libdrm的在图形栈中的位置,都是与内核态驱动交互。
具体功能描述如下:
创建和销毁设备实例:用户可以使用KFD驱动提供的API创建和销毁KFD设备实例。设备实例代表一个GPU设备,用户可以在该实例上执行计算任务。libhaskmt在打开/dev/kfd字符设别后,会使用topology相关的API(系统与节点属性发现)进行设备的具体初始化。
内存管理:KFD驱动提供了内存管理的功能,用户可以使用libhsakmt的API在GPU设备上分配和释放内存。libhsakmt支持多种类型的内存分配与管理,每种内存类型通过HsaMemoryProperties
结构体描述,包含物理地址、大小、类型、可见性等属性。内存管理可以细分为几个功能组:
功能组 | 功能概述 |
alloc/free | 内存的申请和释放,这里的内存包括RAM(GTT, CPU RAM),VRAM |
mmap/munmap | 内存的map,让CPU\GPU能够以自己的视角访问内存 |
copy | 实现CPU-GPU,GPU-GPU间的数据拷贝 |
register/unregister | userptr的支持。把进程用户态的指针注册给GPU,让GPU可以直接访问这些指针,简化编程 |
svm | shared virtual memory功能。让CPU和GPU使用相同的虚拟地址进行访问 |
任务调度与执行:HSA架构采用队列(Queue)机制实现任务调度。每个队列对应一个ring buffer,用户将计算任务包(例如AQL Packet、PM4 Packet)写入队列,GPU异步消费。libhsakmt中的Queue被称为“User Queue",因为直接由用户态操作,不需要内核参与调度。
事件通知和同步:KFD驱动支持事件(Event)机制,用户可注册事件回调函数,实现任务完成、错误、信号等的异步通知。事件机制是实现任务同步与控制的基础。
事件机制与任务队列紧密结合,用户可在任务包中嵌入事件信号,实现任务完成后的自动通知。libhsakmt负责事件与队列的关联管理,确保同步的准确性与高效性。
数据传输:KFD驱动提供了数据传输的功能,用户可以使用API在主机内存和GPU内存之间进行数据传输。这可以实现主机与GPU之间的数据共享和交互。
这些功能使得用户能够更方便地利用GPU设备进行计算和数据处理。
3. 典型调用流程与应用场景
3.1 设备初始化与属性查询
应用调用
hsaKmtOpenKFD
,libhsakmt完成设备文件打开、环境变量初始化、拓扑快照等操作。应用调用
hsaKmtAcquireSystemProperties
获取系统属性,libhsakmt返回缓存的拓扑快照。应用调用
hsaKmtGetNodeProperties
等接口获取各节点详细属性。
3.2 内存分配与数据传输
应用调用
hsaKmtAllocMemory
分配GPU显存或共享内存。应用调用
hsaKmtCopyMemory
实现主机与GPU间的数据拷贝。应用调用
hsaKmtMapMemoryToGPUNodes
实现多节点内存映射。
3.3 任务队列与事件同步
应用调用
hsaKmtCreateQueue
创建任务队列。应用将AQL任务包写入队列,提交给GPU执行。
应用调用
hsaKmtCreateEvent
注册事件,等待任务完成通知。应用调用
hsaKmtWaitOnEvent
实现任务同步与控制。
3.4 多GPU与多进程协作
应用为每个GPU创建独立队列,实现任务的负载均衡与并行执行。
应用通过fork创建子进程,libhsakmt自动处理资源继承与清理,确保多进程协作的安全性。
4. 总结
libhsakmt库的代码量虽然不大,但作为AMD ROCm平台HSA驱动的用户态支撑库,在设备实例管理、内存分配、任务调度、事件同步、数据传输等方面实现了高效、健壮、可扩展的机制。该库是理解AMD HSA机制设计和实现原理的核心库,对于理解KFD内核驱动和上层ROCR(基于libhsakmt API封装的C++类库)的实现有着关键作用。