就像大一学C++,大二学汇编一样,我也写弄了些个月的CUDA,然后,想想,应该开始刨根问底地,去学点在CUDA之下层的东西,可能会对异构这个编程了解的多。
1 简介
OpenCL全称:开发计算语言,是并行程序的开发标准,使用与任何异构平台——包括多CPU、GPU、CPU与GPU结合等。OpenCL由Khronos Group维护。
OpenCL是一个用于异构平台上编程的开放性行业标准。这个平台可以包括 CPU GPU和其他各类计算设备,例如 DSP和Cell/B.E.等等。
OpenCL和CUDA的关系很和谐,前者是异构编程规范标准,后者是英伟达基于OpenCL之上开发的一个更面向程序员的GPUAPI。所以,OpenCL适合于包括英伟达和AMD等的显卡
程序开发。
2 认识OpenCL的框架
2.1 平台模型
[1个host]-[1..N个device] (主机:host;设备:device)
[1个device]-[1..N个CU] (计算单元:CU)
[1个CU]-[1..N个PE] (处理单元:PU)
host端管理者整个平台的所有计算资源,应用程序会从host端向各个 OpenCL设备的处理单元发送计算命令。在一个计算单元内的所有处理单元会执行完全相同的一套指令
流程。指令流可以是 SIMD模式或者SPMD模式。所有由OpenCL编写的应用程序都是从Host启动并结束,最终的计算都发生在PE中。
2.2 内存模型
内存介绍:
全局内存 (global memory):工作空间内所有的工作节点都可以读写此类内存中的任意元素。OpenCL C提供了缓存global buer的内建函数。
常量内存 (constant memory):工作空间内所有的工作节点可以只读此类内存中的任意元素。 host负责分配和初始化 constant buer,在内核执行过程中保持不变。
局部内存 (local memory):从属于一个工作组的内存,同一个工作组中所有的工作节点都可以共享使用该类内存。其实现既可以为 OpenCL执行为其分配一块专有内存空间,
也有可能直接将其映射到一块global buer上。
私有内存 (private memory):只从属于当前的工作节点。一个工作节点内部的private buer其他节点是完全不可见的。
在这点上,基本上和CUDA介绍的内存是一样的。这里的局部内存和CUDA的私有变量差不多一个概念。
内存使用:
在内存的使用上,有两种方式:内存拷贝和内存映射。
拷贝数据是指host通过相应的OpenCL API将数据从host写入到OpenCL设备的内存中或者从 OpenCL设备内存读出数据到 host内存中。
内存映射方法允许用户通过相应 OpenCLAPI将OpenCL的内存对象映射到 host端可见的内存地址空间中。映射之后用户就可以在 host端的映
射地址读写该内存了,在读写完成之后用户必须使用对应 API解除这种映射关系。同拷贝内存方式一样,映射内存也分block和non-block模式。
2.3 执行模型
OpenCL的执行模型可以分为两部分,一部分是在 host上执行的主程序(host program),另一部分是在 OpenCL设备上执行的内核程序(kernels),OpenCL通过主程序来
定义上下文并管理内核程序在OpenCL设备的执行。
执行模式最重要的是分配线程网络,这点和CUDA是一回事,可以引用。
2.4 编程模型
OpenCL支持按数据并行的编程模型和按任务并行的编程模型。
数据并行模型是指同一系的列指令会作用在内存对象的不同元素上,即在不同内存元素上按这个指令序列定义了统一的运算。
在任务并行编程模型是指工作空间内的每个工作节点在执行 kernel程序时相对于其他节点是绝对独立的。在这种模式下对每个工作节点都相当于工作在一个单一的计算单
元内,该单元内只有单一工作组,该工作组中只有该节点本身在执行。用户可以通过如下方法实现按任务并行:
-使用OpenCL设备支持的向量类型数据结构
-同时执行或选择性执行多个kernels
-在执行kernels同时交叉性执行一些native kernels程序
OpenCL提供了两个领域的同步:
-在同一个工作组中所有的工作节点之间的同步
-同一个上下文中不同的 command queues之间和同一个 command queue的不同commands之间的同步
从CUDA了解openCL是在阅读和理解相关CUDA编程知识后,在读《OpenCL中文教程》的一个第一章和第二章的知识汇总,去掉了CUDA编程指南中讲解的雷同知识。在了解和
明白OpenCL是怎么一回事儿后,我将开始openCL的Hello world了,虽然,仅仅一个helloword可能没什么意义,但是,象征性的程序必须写起来。