原文地址:http://www.cnblogs.com/mikewolf2002/archive/2012/01/30/2332391.html

1、OpenCL架构

OpenCL可以实现混合设备的并行计算,这些设备包括CPU,GPU,以及其它处理器,比如Cell处理器,DSP等。使用OpenCL编程,可以实现可移植的并行加速代码。[但由于各个OpenCL device不同的硬件性能,可能对于程序的优化还要考虑具体的硬件特性]。

通常OpenCL架构包括四个部分:

  • 平台模型(Platform Model)
  • 执行模型(Execution Model)
  • 内存模型(Memory Model)
  • 编程模型(Programming Model)

2、OpenCL平台模型

不同厂商的OpenCL实施定义了不同的OpenCL平台,通过OpenCL平台,主机能够和OpenCL设备之间进行交互操作。现在主要的OpenCL平台有AMD、Nvida,Intel等。OpenCL使用了一种Installable Client Driver模型,这样不同厂商的平台就能够在系统中共存。在我的计算机上就安装有AMD和Intel两个OpenCL Platform[现在的OpenCL driver模型不允许不同厂商的GPU同时运行]。

OpenCL平台通常包括一个主机(Host)和多个OpenCL设备(device),每个OpenCL设备包括一个或多个CU(compute units),每个CU包括又一个或多个PE(process element)。 每个PE都有自己的程序计数器(PC)。主机就是OpenCL运行库宿主设备,在AMD和Nvida的OpenCL平台中,主机一般都指x86 CPU。

AMD平台来说,所有的CPU是一个设备,CPU的每一个core就是一个CU,而每个GPU都是独立的设备。

OpenCL平台通常包括一个主机(Host)和多个OpenCL设备(device),每个OpenCL设备包括一个或多个CU(compute units),每个CU包括又一个或多个PE(process element)。 每个PE都有自己的程序计数器(PC)。主机就是OpenCL运行库宿主设备,在AMD和Nvida的OpenCL平台中,主机一般都指x86 CPU。

AMD平台来说,所有的CPU是一个设备,CPU的每一个core就是一个CU,而每个GPU都是独立的设备。

3、OpenCL编程的一般步骤

下面我们通过一个实例来了解OpenCL编程的步骤,假设我们用的是AMD OpenCL平台(因为本人的GPU是HD5730),安装了AMD Stream SDK 2.6,并在VS2008中设置好了include,lib目录等。

首先我们建立一个控制台程序,最初的代码如下:

 1: #include "stdafx.h"2: #include <CL/cl.h>3: #include <stdio.h>4: #include <stdlib.h>5: 6: #pragma comment (lib,"OpenCL.lib")7: 8: int main(int argc, char* argv[])9: {10: return 0;11: }

第一步,我们要选择一个OpenCL平台,所用的函数就是

通常,这个函数要调用两次,第一次得到系统中可使用的平台数目,然后为(Platform)平台对象分配空间,第二次调用就是查询所有的平台,选择自己需要的OpenCL平台。代码比较长,具体可以看下AMD Stream SDK 2.6中的TemplateC例子,里面描述如何构建一个健壮的最小OpenCL程序。为了简化代码,使程序看起来不那么繁琐,我直接调用该函数,选取系统中的第一个OpenCL平台,我的系统中安装AMD和Intel两家的平台,第一个平台是AMD的。另外,我也没有增加错误检测之类的代码,但是增加了一个status的变量,通常如果函数执行正确,返回的值是0。

 1: #include "stdafx.h"2: #include <CL/cl.h>3: #include <stdio.h>4: #include <stdlib.h>5: 6: #pragma comment (lib,"OpenCL.lib")7: 8: int main(int argc, char* argv[])9: {10: cl_uint status;11: cl_platform_id platform;12: 13: status = clGetPlatformIDs( 1, &platform, NULL );14: 15: return 0;16: }

第二步是得到OpenCL设备

这个函数通常也是调用两次,第一次查询设备数量,第二次检索得到我们想要的设备。为了简化代码,我们直接指定GPU设备。

 1: #include "stdafx.h"2: #include <CL/cl.h>3: #include <stdio.h>4: #include <stdlib.h>5: 6: #pragma comment (lib,"OpenCL.lib")7: 8: int main(int argc, char* argv[])9: {10: cl_uint status;11: cl_platform_id platform;12: 13: status = clGetPlatformIDs( 1, &platform, NULL );14: 15: cl_device_id device;16: 17: clGetDeviceIDs( platform, CL_DEVICE_TYPE_GPU,18: 1,19: &device,20: NULL);21: 22: return 0;23: }

下面我们来看下OpenCL中Context的概念:通常,Context是指管理OpenCL对象和资源的上下文环境。为了管理OpenCL程序,下面的一些对象都要和Context关联起来:

—设备(Devices):执行Kernel程序对象。

—程序对象(Program objects): kernel程序源代码

—Kernels:运行在OpenCL设备上的函数。

—内存对象(Memory objects): device处理的数据对象。

—命令队列(Command queues): 设备之间的交互机制。

注意:创建一个Context的时候,我们必须把一个或多个设备和它关联起来。对于其它的OpenCL资源,它们创建时候,也要和Context关联起来,一般创建这些资源的OpenCL函数的输入参数中,都会有Context。

这个函数中指定了和Context关联的一个或多个设备对象,properties参数指定了使用的平台,如果为NULL,厂商选择的缺省值被使用,这个函数也提供了一个回调机制给用户提供错误报告。

现在的代码如下:

 1: #include "stdafx.h"2: #include <CL/cl.h>3: #include <stdio.h>4: #include <stdlib.h>5: 6: #pragma comment (lib,"OpenCL.lib")7: 8: int main(int argc, char* argv[])9: {10: cl_uint status;11: cl_platform_id platform;12: 13: status = clGetPlatformIDs( 1, &platform, NULL );14: 15: cl_device_id device;16: 17: clGetDeviceIDs( platform, CL_DEVICE_TYPE_GPU,18: 1,19: &device,20: NULL);21: cl_context context = clCreateContext( NULL,22: 1,23: &device,24:                25: 26: return 0;27: }

接下来,我们要看下命令队列。在OpenCL中,命令队列就是主机的请求,在设备上执行的一种机制。Kernel执行前,我们一般要进行一些内存拷贝的工作,比如把主机内存中的数据传输到设备内存中。

另外要注意的几点就是:对于不同的设备,它们都有自己的独立的命令队列;命令队列中的命令(kernel函数)可能是同步的,也可能是异步的,它们的执行顺序可以是有序的,也可以是乱序的。

命令队列在device和context之间建立了一个连接。

命令队列properties指定以下内容:

  • 是否乱序执行(在AMD GPU中,好像现在还不支持乱序执行)
  • 是否启动Profiling。Profiling通过事件机制来得到kernel执行时间等有用的信息,但它本身也会有一些开销。

如下图所示,命令队列把设备和context联系起来,尽管它们之间不是物理连接。

1: #include "stdafx.h"2: #include <CL/cl.h>3: #include <stdio.h>4: #include <stdlib.h>5: 6: #pragma comment (lib,"OpenCL.lib")7: 8: int main(int argc, char* argv[])9: {10: cl_uint status;11: cl_platform_id platform;12: 13: status = clGetPlatformIDs( 1, &platform, NULL );14: 15: cl_device_id device;16: 17: clGetDeviceIDs( platform, CL_DEVICE_TYPE_GPU,18: 1,19: &device,20: NULL);21: cl_context context = clCreateContext( NULL,22: 1,23: &device,24: NULL, NULL, NULL);25: 26: cl_command_queue queue = clCreateCommandQueue( context,27: device,28: CL_QUEUE_PROFILING_ENABLE, NULL );29: 30: return 0;31: }

OpenCL编程入门相关推荐

  1. 【浅墨著作】 OpenCV3编程入门 内容简介 勘误 配套源代码下载

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 经过近一 ...

  2. 【OpenCV学习】 《OpenCV3编程入门》--毛星云 01 邂逅OpenCV(OpenCV基本概念与基本架构) ROS系统上的运用(python实现)

    对 <OpenCV3编程入门>第一章的学习笔记:理解什么是计算机视觉,什么是OpenCV,以及其中的联系等等. PS:此书为2014年出版,opencv的版本和接口也与现在有些不一致了,作 ...

  3. 【《OpenCV3编程入门》内容简介勘误配套源代码下载

     录 (?) [+] 一前言 二内容安排 三适合阅读本书的读者 四书本目录 第一部分 快速上手OpenCV 1 第1章 邂逅OpenCV 3 1 OpenCV周边概念认知 4 2 OpenCV基本 ...

  4. OpenCL编程详细解析与实例

    OpenCL编程详细解析与实例 C语言与OpenCL的编程示例比较 参考链接: https://www.zhihu.com/people/wujianming_110117/posts 先以图像旋转的 ...

  5. python编程求圆的面积案例_Python实用案例编程入门:第七章 调式手段

    本章的主题为调试手段,这是程序开发必不可少的步骤,也是占用时间最多的环节.在程序员的正常开发工作中,调试工作至少占据1/3的时间,而实际编码工作相对占用实际比较少.因此,无论您是初学者,还是编程兴趣爱 ...

  6. 《C++游戏编程入门(第4版)》——1.12 习题

    本节书摘来自异步社区出版社<C++游戏编程入门(第4版)>一书中的第1章,第1.1节,作者:[美]Michael Dawson(道森),更多章节内容可以访问云栖社区"异步社区&q ...

  7. 编程入门到进大厂,你需要这套学习架构

    我相信大多数学习编程的同学都有着对大公司的憧憬.技术.声望.薪资.福利,这些都足以成为吸引你进入大厂的理由. 但是,如何进入大厂呢? 对于很多同学来说,通往大厂的道路并不明朗,不知道是否有希望,也不知 ...

  8. 《C++游戏编程入门(第4版)》——1.8 Lost Fortune简介

    本节书摘来自异步社区出版社<C++游戏编程入门(第4版)>一书中的第1章,第1.8节,作者:[美]Michael Dawson(道森),更多章节内容可以访问云栖社区"异步社区&q ...

  9. [译]函数式响应编程入门指南

    原文地址:An Introduction to Functional Reactive Programming 原文作者:Daniel Lew 译文出自:掘金翻译计划 本文永久链接:github.co ...

  10. 《C++游戏编程入门(第4版)》——2.4 使用带else子句的if语句序列

    本节书摘来自异步社区出版社<C++游戏编程入门(第4版)>一书中的第2章,第2.4节,作者:[美]Michael Dawson(道森),更多章节内容可以访问云栖社区"异步社区&q ...

最新文章

  1. suse10 linux安装,SuSE10.2 安装手记
  2. [转载] python数组的使用
  3. 如何评价「施一公请辞清华大学副校长,全职执掌西湖大学」?你如何看待西湖大学的发展前景?
  4. java 图片路径裁剪图片,Java中实现图片的裁剪
  5. Cocos2d-x移植Android 常见问题处理办法
  6. 2018我们要赢 (5 分)
  7. python中的zip函数详解_python中的 zip函数详解
  8. dll注册,但是对DllRegisterServer的调用失败,错误代码0x80070716
  9. MatlabSimulink中找不到Carsim_s_function的解决办法
  10. 一文搞懂css 2D动画效果
  11. Python变量与字符串
  12. vue中DPlayer视频播放器使用方法
  13. lol网通服务器位置,LOL转区系统地址在哪里 国服转区方法介绍
  14. PAT--1094 谷歌的招聘(C语言)
  15. 移动硬盘无法读取怎么修复?这一招好用
  16. php一键安装的环境包,php环境搭建的一键安装包有哪些?
  17. Android懒人库
  18. 基于GBT28181:SIP协议组件开发-----------第五篇SIP注册流程eXosip2实现(二)
  19. 题解 【提高】小 X 学游泳(swim)
  20. 国外APP外包开发及上线流程

热门文章

  1. [it-ebooks]电子书列表
  2. 基于Java的学生成绩管理系统
  3. Linux命令行下WEP密码破解(通用,也可非BT平台)
  4. RIME中州韵输入法词库扩充(搜狗词库,QQ拼音词库,清华词库,拆字词库U模式等)
  5. 第十三届蓝桥杯第二场模拟赛题解
  6. Windows远程桌面连接Ubuntu 16.04
  7. 小学三年级计算机认识键盘教案,第8课 认识键盘大家庭 教案
  8. 笨办法学Python,其实一点都不笨
  9. 饭卡管理系统学生E-R图
  10. Python scrapy 将mmjpg图片下载到本地