GPU的OPENCL编程2(CPU和GPU数据交互和GPU与global id local id的关系)

本文详细介绍了OpenCL编程中GPU与CPU内存的交互方式,包括clCreateBuffer和clCreateImage函数创建的内存对象,以及如何通过clSetKernelArg传递参数。内容强调了OpenCL的并行计算特性,如内存划分和clEnqueueNDRangeKernel的使用,展示了如何将循环消除并利用工作项和工作群组实现数据并行计算。还讨论了在特定SOC平台上设置工作大小的注意事项,并给出了实例来解释全局ID和局部ID在计算中的作用。

在不同的架构上GPU和CPU的情况不一样,在电脑上GPU可以有很大的DDR显存存放数据,SOC上GPU的显存和CPU是同一个DDR,GPU可能会提供一个小的SRAM作为缓存该缓存不用于CPU和GPU交互数据。这个章节的细节内容建议查看“OpenCL Programming Guide”这本书。
在Opencl编程中和普通CPU编程有很大的不同,提供给GPU的共享内存需要通过clCreateBuffer或clCreateImage申请。传输变量内存地址,传输Kernel的参数都必须通过clSetKernelArg函数调用。CPU和GPU间的数据共享,参数传递都必须通过封装好的函数处理,不能直接简单的用变量名称共享。

在这里插入图片描述
图1 :CPU和GPU的内存关系

CPU与GPU的内存空间交互

申请给CPU申请和GPU交互的DDR内存空间主要是以下3种方式:
1.clCreateBuffer函数是创建缓存对象是与图像处理无关内存。
2. clCreateImage2D函数是创建2D图像格式空间内存。
3. clCreateImage3D函数是创建3D图像格式空间内存。
对于Image的创建的内存使用一些和Image相关的函数调用比如:clEnqueueMapImage、clEnqueueReadImage、SaveImage、可以参考“Images and Samplers章节”。
对于为什么需要Image这样的一个内存对象我认为主要是方便使用,对于图像 Specifying and querying for image formats(可以设置和查询图像格式),可以使用sampler快速调用函数获取你所需要的图像,而无需像内存图像一样各种计算后你才能获取到图像所在的位置指针。clGetMemObjectInfo能防护图像信息又能返回内存对象信息,可以将获取图像后方便转换为内存操作。

CPU对申请的Buffer和Image空间访问可以通过2种方式。
1.通过Buffer和Image对应的read*和write函数进行访问。
2.通过Buffer和Image对应的**map
内存映射函数进行内存直接访问。

内存数据划分

使用Opencl的目的就是为了并行计算,大量的数据并行计算一个整块的数据如何分配给每个GPU对并行的性能提升非常重要。GPU的优势为重复执行相同的算法操作,判断语句和跳转语句在GPU上运行效率奇低。我们做一个大数组排序、取最大值等运算时会用到内存划分。数组不用内存划分的话可能需要使用FOR循环的方式很难发挥GPU并行运算的效能。clEnqueueNDRangeKernel是clEnqueueKernel执行内核控制的扩展。查看“Writing a Data-Parallel Kernel Using OpenCL C”章节。
一个小的程序例子进行一下说明有帮助理解:
C语言的单个循环例子:

void scalar_add (int n, const float *a, const float *b, float *result)
{
   
   
 int i;
for (i=0; i<n; i++)
 result[i] = a[i] + b[i];
}

在使用clEnqueueNDRangeKernel后可以变成

kernel void
scalar_add (global const 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值