图3-3展示了MXMACA编程框架和MXMACA程序结构全景图。MXMACA程序是一个定义了上下文的宿主机程序。如图所示,一个MXMACA上下文对象内具有两个计算设备,一个CPU设备和一个GPU设备,每个计算设备都具有自己的命令队列,故MXMACA程序有两个命令队列:一个是面向GPU的有序命令队列,另一个是面向CPU的乱序命令队列。MXMACA宿主机程序定义一个程序对象,这个程序对象在编译后将为两个MXMACA设备(CPU和GPU)生成核函数。接下来,MXMACA宿主机程序定义程序所需的内存对象,并将其映射到核函数的参数中。最后,MXMACA宿主机程序将命令放入命令队列来执行这些核函数。
MXMACA编程使用由C/C++语言扩展生成的注释代码在异构计算系统中执行应用程序。一个异构环境包含多个CPU和GPU,每个CPU和GPU都由一条PCIe总线隔开,因此,需要注意区分这两方面的内容:
● 主机端:CPU及其内存(主机内存)。
● 设备端:GPU及其内存(设备内存,也叫显存)。
为了区分不同的内存空间,本书的很多地方使用以h_为前缀的名称表示主机内存变量,以d_为前缀的名称表示设备内存变量。
图3-3 MXMACA编程框架和MXMACA程序结构全景图
核函数(Kernel)是MXMACA编程模型的重要组成部分,其代码在GPU上运行。多数情况下,主机端可以独立地对设备进行操作,而核函数一旦启动,管理权限将立刻返回给主机端,释放CPU执行其他的任务。典型的MXMACA程序包括并行代码和串行代码,如图3-4所示。串行(或并行)代码在CPU上执行,而并行代码在GPU上执行。主机端代码使用ANSI C/C++语言编写,而设备端代码使用MXMACA C/C++语言编写,mxcc为主机端和设备端生成可执行代码。
一个典型的MXMACA程序实现流程应遵循以下模式。
● 把数据从CPU内存复制到GPU内存。
● 调用核函数对GPU内存的数据进行处理。
● 将数据从GPU内存传送回CPU内存。
因此,首要学习的是为主机端和设备端分配内存,以及如何在CPU和GPU之间复制数据。在这种程序员管理模式控制下的内存和数据可以优化应用程序并使系统利用率最大化。
图3-4 MXMACA C/C++程序典型范式