注意:   如果是从显存到显存不是用writebuffer而是用copybuffer

以前就听说OPenCL,今天就特地使用了一下,我的机器是N卡,首先装上了CUDA的开发包,由于CUDA对OPenCL支持比较好,就选择了N卡上的GPU并行计算。

OPenCL是一个开放的标准和规范,全程是开放计算库,主要是发挥计算机的所有计算资源,包括CPU、GPU、多核等。所以说OPenCL是一个跨硬件和软件平台的开放标准,在此框架下开发的并行计算程序很容易就能移植到其他平台上,也许是这样吧。其实,关于GPU的并行计算的大致思路一般都是CPU向GPU发送一个计算指令,然后把数据拷贝的GPU的显存中参与计算,然后将计算好的显存中的数据拷贝到主机内存中,虽然说,过程大概就是这样,但是其中涉及到的细节可是特别多。下面就以一个简单的例子为例讲述OPenCL编程开发的一般步骤和模型。

第一步,首先获得可以参与计算的OPenCL平台个数

cl_uint numPlatforms = 0;   //GPU计算平台个数
  cl_platform_id platform = NULL;
  clGetPlatformIDs(0,NULL,&numPlatforms);

第二步,获得平台的列表,并选择其中的一个作为计算的平台

//获得平台列表
  cl_platform_id * platforms = (cl_platform_id*)malloc(numPlatforms * sizeof(cl_platform_id));
  clGetPlatformIDs (numPlatforms, platforms, NULL);  //轮询各个opencl设备
  for (cl_uint i = 0; i < numPlatforms; i ++)
  {
    char pBuf[100];
    clGetPlatformInfo(platforms[i],CL_PLATFORM_NAME,sizeof(pBuf),pBuf,NULL);
    printf("%s\n",pBuf);
    platform = platforms[i];
  }  free(platforms);

第三步,获得硬件设备以及生成上下文

//获得GPU设备
  cl_device_id device;
  status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL);  //生成上下文
  cl_context context = clCreateContext(0, 1, &device, NULL, NULL, &status);

至此,OPenCL的初始化工作已经完成,最好将这个过程封装成一个函数。

第四步,装载内核程序代码以及生成program

//装载内核程序
  size_t szKernelLength = 0;
  size_t sourceSize[] = {strlen(kernelSourceCode1)};  char *cFileName = "kernel.cl";  char * cPathAndName= shrFindFilePath(cFileName, argv[0]);
  const char* kernelSourceCode = oclLoadProgSource(cPathAndName, "", &szKernelLength);  cl_program program = clCreateProgramWithSource(context,1,&kernelSourceCode,&szKernelLength,&status);  //为所有指定的设备生成CL_program
  status = clBuildProgram(program,1,&device,NULL,NULL,NULL);
  size_t len = 0;
  char buf[2048];
  if (status != CL_SUCCESS)
  {
    status = clGetProgramBuildInfo(program,device,CL_PROGRAM_BUILD_LOG,sizeof(buf),buf,&len);
    printf("%s\n", buf);
    exit(1);
  }

第五步,创建一个命令队列,将这个命令队列放入内核程序中执行

//创建一个opencl命令队列
  cl_command_queue commandQueue = clCreateCommandQueue(context,device,0,&status);  //创建opencl buffer对象
  cl_mem outputBuffer = clCreateBuffer(context,CL_MEM_ALLOC_HOST_PTR,4*4*4,NULL,&status);  //得到指定名字的内核实例句柄
  cl_kernel kernel = clCreateKernel(program,"hellocl",&status);  //为内核程序设置相应的参数,也就是函数传参
  status = clSetKernelArg(kernel,0,sizeof(cl_mem),&outputBuffer);  //将一个kernel放入队列
  size_t globalThreads[] = {4,4};
  size_t localThreads[] = {2,2};  //开始在设备上执行核函数
  status = clEnqueueNDRangeKernel(commandQueue,kernel,2,NULL,
    globalThreads,localThreads,0,NULL,NULL);
  status = clFinish(commandQueue);

第六步,将计算结果拷贝到主存中

//将GPU本地内存中的数据拷回到host端的内存中
  unsigned int *outbuffer = new unsigned int[4*4];
  memset(outbuffer,0,4*4*4);
  status = clEnqueueReadBuffer(commandQueue,outputBuffer,
    CL_TRUE,0,4*4*4,outbuffer,0,NULL,NULL);

第七步,显示及清理内存

printf("out:\n");
  for (int i = 0; i < 16; i ++)
  {
    printf("%x ",outbuffer[i]);
    if ((i+1)%4 == 0)
    {
      printf("\n");
    }
  }  //清理部分
  status = clReleaseKernel(kernel);
  status = clReleaseProgram(program);
  status = clReleaseMemObject(outputBuffer);
  status = clReleaseCommandQueue(commandQueue);
  status = clReleaseContext(context);
  delete outbuffer;

核函数如下:

__kernel void hellocl (__global uint *buffer)
{

  uint dim = get_work_dim();   //获得工作空间的维度信息
  size_t gidx,gidy,gidz;
  size_t gsizx,gsizy,gsizz;
  if(dim == 1)
  {
    gidx = get_global_id(0);
    gsizx = get_global_size(0);
    buffer[gidx] = gidx;
  }  else if(dim == 2)
  {
    gidx = get_global_id(0);
    gidy = get_global_id(1);
    gsizx = get_global_size(0);
    gsizy = get_global_size(1);
    buffer[gidx+gidy*gsizx] = (1<<gidx)|(0x10<<gidy);;
  }  else
  {
    gidx = get_global_id(0);
    gidy = get_global_id(1);
    gidy = get_global_id(2);
    gsizx = get_global_size(0);
    gsizy = get_global_size(1);
    gsizz = get_global_size(2);
    buffer[gidx + gidy*gsizx + gidz*gsizx*gsizy] = gidx;
  }
}

运算结果显示如下图:

这只是最简单的程序,复杂算法的并行化还需要深入研究。

OpenCL入门程序相关推荐

  1. 详细程序注解学OpenCL一 环境配置和入门程序

    本专栏是通过注解程序的方法学习OpenCL,我觉得一个一个地去抠原理也不是办法,干脆直接学习程序,然后把相关原理都直接注解到程序语句当中. 原创地址:http://blog.csdn.net/kend ...

  2. rabbitMQ入门程序

    1.生产者 /*** rabbitMQ入门程序消费者** @author xiaoss* @date 2020年10月27日 22:02*/ public class Producer01 {//队列 ...

  3. SpringMVC学习(一)———— springmvc框架原理分析和简单入门程序

    一.什么是springmvc? 我们知道三层架构的思想,并且如果你知道ssh的话,就会更加透彻的理解这个思想,struts2在web层,spring在中间控制,hibernate在dao层与数据库打交 ...

  4. java slfj教程_SLF4J入门程序

    本篇文章帮大家学习SLF4J入门程序,包含了SLF4J入门程序使用方法.操作技巧.实例演示和注意事项,有一定的学习价值,大家可以用来参考. 在本章中,我们将学习如何编写使用SLF4J的简单基本记录器程 ...

  5. java mvc框架代码_JAVA技术学习笔记:SpringMVC框架(内附入门程序开发代码)

    原标题:JAVA技术学习笔记:SpringMVC框架(内附入门程序开发代码) JavaEE体系结构包括四层,从上到下分别是应用层.Web层.业务层.持久层.Struts和SpringMVC是Web层的 ...

  6. IDEA下——Spring入门程序

    创建一个Maven的项目,我的项目结构如下: 在pom文件里写下需要导入的依赖: <?xml version="1.0" encoding="UTF-8" ...

  7. mybatis学习笔记(3)-入门程序一

    2019独角兽企业重金招聘Python工程师标准>>> mybatis学习笔记(3)-入门程序一 标签: mybatis [TOC] 工程结构 在IDEA中新建了一个普通的java项 ...

  8. 网络爬虫(Web crawler)|| 爬虫入门程序

    网络爬虫 网络爬虫(Web crawler),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本 爬虫入门程序 环境准备 JDK1.8 IntelliJ IDEA IDEA自带的Maven 环境 ...

  9. 第一次运行OSG入门程序失败记和搞定的情况

    一 OSG简介 OpenSceneGraph(简称OSG)使用OpenGL技术开发,是一套基于C++平台的应用程序接口(API),它让程序员能够更加快速.便捷地创建高性能.跨平台的交互式图形程序.它作 ...

  10. 用C#进行ArcGIS 10 Engine 开发 - 安装配置和入门程序说明

    一 安装 1   其安装包解压后如下图: 文件比较大,有3G多,无法上传:如果网上下不到,可联系鄙人q号513979805,发一份给你:不过上图的授权文件我记不清哪个能用了,不行的话需要自己在网上找可 ...

最新文章

  1. CNN(Convolutional Neural Networks)算法
  2. Codeigniter 用户登录注册模块
  3. 实战小技巧系列(4):WinForm简单步骤制作
  4. linux删除之前的文件日志
  5. Excel向数据库插入数据(执行一次只需连接一次)-batch简单使用
  6. 2020 年软件开发趋势预测!
  7. 启动项目无法打印日志处理及logback简单使用
  8. 【NOIP2005】【Luogu1051】谁拿了最多奖学金
  9. “朝三暮四”与“BPO”
  10. 可信人工智能白皮书(概要)
  11. matlab菲涅尔衍射光强分布,矩孔菲涅耳衍射的光强分布.pdf
  12. 漫谈数据结构系列(一)之僧敲月下门
  13. Android4.4电池电量命令行查看
  14. nacos 未读取到合法数据,请检查导入的数据文件
  15. 如何利用新闻传播进行产品网络推广?
  16. C++上机实验三第2题
  17. Redis 性能优化 13 条军规
  18. 平稳过程与广义平稳过程(WSS)
  19. children的childNodes区别
  20. 【微信小程序】微信小程序提示Do not have handler in component

热门文章

  1. 新消费万字之辩 | “疯狗浪”时代来临,品牌如何结构性增长?
  2. JavaScript代码如何在VScode进行调试?
  3. wine 运行QQ的问题
  4. 【转】opencv中widthStep不一定等于width*nChannels的原因
  5. shm 共享内存 android,共享内存
  6. STM32 BOOT设置以及对应的意义
  7. 什么是网络,网络类型,网络结构
  8. hadoop权威指南-MapReduce气象程序实现过程
  9. 基于OCR图像识别技术的发票采集管理系统及方法
  10. wps页码从指定页开始_wps怎么自动生成页码以及设置页码从第三页开始