OpenCL并行计算3-主机编程之数据的传输和划分

要想让设备执行主机传递过来的任务,至少需要三部分:执行的任务的指令,存储数据的缓存,结果返回。

数据在主机与设备之间的传输:

1.设定内核参数

我们将内核通过命令队列传递给设备,仅仅只是将卡牌给了玩家。我们必须要给内核传递参数才能让设备执行内核。缓存对象的主要作用是将主机和设备之间传递数据的桥梁。我们可以设定三种形式的内核参数:基本数据类型指针,内存对象指针,采样器对象指针。一般情况下我们所创建的内存对象都是buffer对象,除非你的数据中包含的是像素数据则需创建image对象,缓存对象和图像对象的数据结构都是cl_mem.创建缓存对象时的参数解释:
clCreateBuffer(cl_context context, cl_mem_flags options, size_t size,void *host_ptr, cl_int *error)
cl_mem_flags :这个参数一般是几个参数的组合如下表所示。
CL_MEM_READ_WRITE :允许设备读写
CL_MEM_WRITE_ONLY :只允许设备写,设备分配内存,主机不可以分配。
CL_MEM_READ_ONLY :只允许设备读
CL_MEM_USE_HOST_PTR :共用主机的内存,但是数据没有安全性可言。
CL_MEM_COPY_HOST_PTR :copy主机传递的数据
CL_MEM_ALLOC_HOST_PTR:不清楚。
总结:要将主机的数据传递给设备时:CL_MEM_READ_WRITE |CL_MEM_COPY_HOST_PTR
设备返回计算结果给主机时:CL_MEM_WRITE_ONLY
缓存对象主要是为了给设备使用的,其本质就是device memory。通过对内核函数进行参数设置,可以将这些对象发送到设备上,但也可以通过主机与设备之间的数据传输命令来传递。

2.内存对象的传输命令

主机将命令发送到命令队列的过程称之为入列,命令其实就是函数。入列数据传输命令可以分为三大类:发起读/写数据传输的函数,映射和解映射内存的函数,以及在不同内存对象之间复制数据的函数。注意这些函数没有创建新的内存对象,它们访问的数据所在的内存对象已经通过核函数的方式传递给了设备。
a)读/写数据传输,主要是完成主机内存与设备内存之间数据的传输。
b)映射内存对象,都是将设备的内存映射至主机上,让后主机可以读取和修改内存。内存映射的运行性能远高于普通的读/写函数。
c)内存对象间的数据复制,与以上主机内存和内存对象间的数据传输不同,这种方式是内存对象间的数据复制,这个操作主要发生在设备之中。

单个设备(GPU)上数据和计算任务的分配:

在单个设备上进行数据划分的函数只有一个:clEnqueueNDRangeKernel,其允许在设备的不同处理资源间分配、执行内核。GPU的优势在于做计算,CPU的优势在于做流程控制,我们将内核给GPU运行,故GPU中只会运行进行最内层的一次迭代,这一次迭代过程称之为工作项(Work-item)。内核与工作项的区别:内核表示的是一系列处理数据任务的集合,工作项是针对某个特定数据集的内核实现。
例如:

for(i=is;ii++)
    for(j=js;jj++)
        for(k=ks;k[i][j][k]);

work_dims:数据维度=全局id中的元素数量=数组的维度 =3;
global_work_offset:各个维度上全局ID的偏移量={is,js,ks}
global_work_sizes:表示各个维度上所要处理的工作项的数量,一般是各个循环中循环的次数={ie,je,ke}
local_work_size:各个维度上一个工作组中工作项的数量。
一个工作项=最深层的一次迭代 = process(a[i][j][k]);

工作组:由访问相同处理资源的工作项组成。组中的各个工作项可以访问高速内存(局部内存)的同一块内存。组中的工作项可以通过栅栏(fence)和障碍(barrier)的方式来进行同步。能够支持工作租的处理资源被称之为处理单元。

小结:OpenCL的数据处理及分配

设备与主机之间数据传输的载体是cl_mem结构。内存对象的传输过程:
a)通过存在的数据创建内存对象。
b)调用clSetKernelArg将这个内存对象设置为内核的参数。这样内核在执行过程中就可以将内存对象当作参数来进行访问。
内存对象分为缓存对象和图像对象。缓存对象以一维的形式保存普通数据,图像对象以二维或三维的方式保存数据。OpenCL提供了入列函数和内存映射的方式实现主机与设备之间的数据通信。
数据划分是进行高性能OpenCL应用程序不可避免的话题。分割操作的基本单元是工作项,对应的是循环中最深层次的迭代,每个工作项会有一个全局ID,用来标识代码所访问的数据位置。如果工作项之间需要进行同步化处理,则需要对这些工作项进行工作组的划分,各个工作组将会分配到设备上相应的计算单元来执行。

你可能感兴趣的:(并行计算)