在了解主机编程的数据结构之前,我们主要关注的2个问题,一是创建这种数据结构的函数,一种是”提供被创建数据结构信息”的函数。以下通过模拟打牌游戏来理解各个对象。
平台:
平台就是指SDK。在编程之前我们要了解主机上安装了那些平台的sdk,通过SDK我们获取链接在运用那些硬件(GPU),因为每个公司的都会为自己的处理器提供一套sdk。cl_platform_id结构对应的是安装在主机上一种不同的OpenCL的具体实现。一般采用”函数调用-内存分配-函数调用”的模式。
设备:
表示可以利用或进行计算的GPU设备,我们用cl_device_id结构来表示某个设备。设备代表的是牌局中的每个玩家,主机就是庄家。
上下文:
1)Host是通过上下文(Context)这个容器来管理Device的,同一个上下文中设备必须由同一平台(AMD和Nvidia不属于同一平台)来提供,上下文也可以只用来标识一部分设备,上下文是命令队列创建的基础。
2)可以利用引用次数来标记上下文的个数。一个平台中可以有很多上下文,主机是通过上下文来管理所连接设备的。
上下文就是牌局中的牌桌。
程序:
我们将所有设备将要运行的代码保存在程序中,内核是设备上执行的某个函数,程序是由一堆内核所组成的。设备的编译器必须通过OpenCL的clBuildProgram来对程序进行访问。程序就是牌堆。
内核:
为了将程序中的函数部署到设备,必须要将函数打包为内核,使用内核的好处就是它们都是可以部署的,简单说就是可以给每个线程执行。内核可以被发送到命令队列中,然后发送给设备。内核是玩家手中的一张牌,设备是玩家。内核是设备程序执行的入口点。是主机上调用设备上运行的一个函数。内核是在运行的时候由设备编译的,所有在设备上运行的函数都是在运行时编译的。
命令队列:
命令队列是沟通宿主机和设备之间的桥梁,命令对列的作用就是收集内核。内核只能通过命令队列传递给设备,命令队列是主机和设备通信的纽带。每一个设备都会有自己的命令队列。数据可以在设备和主机之间传递,但是命令只能从主机到设备之间单向传递。命令队列可以有序或无序的执行命令,默认情况下是按接收命令的顺序执行的。
命令队列是Host实现对Device控制的一种机制,当内核入列时,设备便会执行相应的函数。命令队列是玩家的手牌(好比庄家发给玩家的一手牌,一个由牌组成的序列)。内核入列命令和内核执行命令是一样的(入列=执行)。
内存对象 :
内存对象是主机和设备之间进行数据交换的载体,就像”共享内存”的方式一样。