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)

当需要分配设备内存时:

  1. 通过 mcSetDevice(deviceId) API选择需要分配内存的设备,若不显示指定设备,则默认分配到 deviceId=0

  2. 通过 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。