OpenCL入门(一):简单概念

来源:互联网 发布:java多态笔记 编辑:程序博客网 时间:2024/06/01 08:25

这段时间一直在进行OpenCL方面的学习。感觉OpenCL是一个非常厉害的程序开发体系,他的作用就是使用同一套语言开发出来的程序在不同的平台上都可以跑。

OpenCL现在主要用于并行开发,并行的意义就是很多处理器拿着不同的原材料做完全相同的处理得到不同的结果。这个“同时”的好处在于,由于处理过程完全相同,那么我直接将任务分发给所有可以执行这项任务的单元,这样所有人都可以独立地进行处理。背景理解可以参考这边文章:链接

OpenCL运行包含2个环境(也叫2个端):主机端(host)和设备端(device)。

host端绝大部分情况就是我们所说的CPU;设备端则是那些支持OpenCL的设备,比如显卡、FPGA等。他们的作用分别是:主机端负责调度任务,是指挥的角色;设备则负责具体的并行处理,是劳动者的角色。

下面,我通过梳理OpenCL通用的开发流程来说明上面这些东西的意义:

(1)找平台Platform(在Host端执行)

找平台Platform基本等同于找当前Host端(装CPU的那台电脑上)有几个OpenCL开发环境,比如你有NVIDIA的CUDA环境就算一个CUDA的Platform,你有Altera的OpenCL环境就算Altera的platform。换句话说,找Platform就是找你那个支持OpenCL的设备是哪家公司的产品,基本上一家公司就算一个platform(当然也不排除1家公司多个platform的情况)。

(2)找设备Device(在Host端执行)

找到平台Platform后,你确定了主机上有哪些公司提供的OpenCL开发环境了,接下来,你需要确定你电脑上可以用于并行处理的设备有哪些,比如安装好的显卡和安装好的FPGA板(当然驱动配置好是前提)。

(3)创建上下文Context(在Host端运行)

在我看来,上下文这个东西就像是你召集小伙伴开会需要一个名目一样,比如以煮饭为目的召集一帮人来干活,一部分人负责买菜,一部分做菜。这个煮饭的名目就算是一个上下文,在这个上下文内(名目下)不同设备(负责不同大任务的人群)才有相互协作的理由。

(4)创建命令队列Command_queue(在Host端运行)

依照煮饭的那个例子,有一个协同工作的名目之后,每一个部分的人就要开始自己的工作了(相当于设备准备开始处理了)。此时,这些人就需要为自己负责的部分列一个任务清单,比如做菜的那部分人列的清单是先做什么菜,先炒什么配料等,这些小任务的先后顺序在这个清单中有先后规定。命令队列就是这样的清单,它里面说明了设备执行任务处理的先后顺序。

(5)创建3大对象(在Host端运行)

OpenCL开发是面向对象的程序开发,所以接下来需要搞定3大对象:创建内存对象、创建并编译程序对象、创建内核对象。

创建内存对象就相当于你煮饭需要准备原料一样,进行任务处理之前你需要把要用到的数据准备好(并放置到相应的位置),数据就是以内存对象的形式进行准备和放置。

创建和编译程序对象只能通过程序开发的角度进行理解。以编写helloWorld程序为例,你需要先写一份cpp代码,然后编译成exe文件再执行。那么创建和编译程序对象就是这样一个过程,只是面向对象的OpenCL编程将程序对象化了。

创建内核对象则是从编译好的程序对象中将单独的编译好的OpenCL内核函数拿出来。这样看来,一个.cl文件里面可以包含很多kernel函数(也就是内核函数),那么由这个.cl文件编译而成的就是程序对象,里面每一个kernel函数都被编译成单独的kernel对象。

(6)设置内核参数(在Host端运行)

现在内核函数已经编译好了,但是此时的内核函数是外部的文件,这个文件在运行时可能需要传参数进去(与执行含参数的函数原理一样,需要传外部参数进去)。所以你需要在主机上指定这些kernel函数在运行时需要传哪些参数进去。

(7)执行内核参数(在Device端运行)

一切准备就绪,设备就开始按照命令队列里面的顺序开始给具体的处理单元分发任务了。在煮饭的例子中,负责一个具体任务的人群(对应一个设备)开始给下面每一个人都分配任务,如果此时任务清单(对应命令队列)上说此时的任务时切菜,那么每一个人(对应每一个处理单元)就从准备好的材料(对应内存对象)中拿出一份菜(对应具体数据)出来同时做同样的切菜过程(对应执行同一份kernel函数)。



上述就是OpenCL程序开发中最基本的7个流程。可以看出准备工作都是在Host主机端完成的,只有具体的并行任务才交给了设备来运行。


0 0
原创粉丝点击