3. 编程模型
3.1. 设备管理
一个服务器主机系统可以有多个设备,设备之间可以通过PCIe或者MetaXLink进行通信。曦云系列GPU提供了查询和管理设备的方法。通过这些方法,可选择合适的设备进行任务工作。
本节主要介绍方法接口,具体示例代码,参见《曦云® 系列通用GPU 运行时API编程指南》。
3.1.1. 查询设备信息
主机线程可以通过调用 mcGetDeviceCount() 随时查看可以使用的GPU数量,并通过调用 mcGetDeviceProperties() 查询每个设备的属性。
3.1.2. 选择运行设备
主机线程可以通过调用 mcSetDevice() 选择要执行操作的设备。在当前设置的设备上进行设备内存分配和内核启动;创建与当前设置的设备相关联的流和事件。
如果未调用 mcSetDevice() ,则当前设备为设备0。
3.1.3. 初始化设备
当主机线程调用 mcDeviceReset() 时,会破坏主机线程当前操作设备(即选择运行设备中定义的当前设备)的主要上下文。
将此设备作为当前设备的任何主机线程,进行下一次运行时函数调用时,将为此设备创建新的主要上下文。
3.2. 内存管理
曦云系列GPU内存可以分为主机系统内存(system memory)和设备内存(device memory)。
3.2.1. 内存申请与释放
申请系统内存时,使用 mcMallocHost() API。
mcMallocHost(void **ptr, size_t sizeBytes, unsignet int flags)
当需要分配设备内存时:
通过
mcSetDevice(deviceId)API选择需要分配内存的设备,若不显示指定设备,则默认分配到deviceId=0。通过
mcMalloc(void **ptr,size_t sizeBytes)API分配设备内存。使用上述接口分配出来的内存均为SVM内存,即设备和CPU均可以访问。
系统内存和设备内存的释放分别使用 mcFreeHost(void *ptr) 和 mcFree(void *ptr) 。
3.2.2. 内存拷贝
曦云系列GPU支持系统内存与设备内存之间进行拷贝,或者设备内存之间以及系统内存之间拷贝。内存拷贝分为两种类型:阻塞拷贝与异步拷贝。
阻塞拷贝与glibc提供的
memcpy类似,可以使用mcMemcpy()API,直到全部数据拷贝完成,该API才会返回。异步拷贝依赖于流,异步拷贝将拷贝任务放到流队列后,API直接返回,需要用户通过流机制查询是否执行完成。异步拷贝使用
mcMemcpyAsync()APl。