欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld。 技术交流QQ群:433250724,欢迎对算法、技术、应用感兴趣的同学加入。

并行编程的需求是显而易见的,其最大的难题是找到算法的并行功能,同时必须处理数据的共享和同步。但是,因为每一个算法都是不一样的,很难有通用的并行功能——粒度都有可能是不一样的。OpenCL提供了很多并行的抽象模型,因此算法开发人员可以在不同粒度上开发并行的算法,以及数据的共享和同步。


一般来说,并行编程有两种大类型——分散收集(scatter-gather)与分而治之(divide-and-conquer)。
  1. 分散收集(scatter-gather):数据被分为子集,发送到不同的并行资源中,然后对结果进行组合,也就是数据并行;
  2. 分而治之(divide-and-conquer):问题被分为子问题,在并行资源中运行,也就是任务并行。

看一个最简单数据并行实例:

理想情况是,所有的乘法都可以并行执行,而不是串行执行。

任务并行的示意图:

比如多CPU系统,每个CPU执行不同的线程。还有一类流水线并行,也属于任务并行:

流水线的每一个任务会处理不同的数据,这里不是串行的!而是流水线并行的,数据从一个任务传送到另外一个任务中,同时前一个任务又处理新的数据。

数据共享与同步

这个大概是并行编程最难的部分,一般来说,下面两种情况需要有数据的同步:(1)一个子任务的输入依赖于另一个子任务的输出;(2)中间结果需要汇总合并。在OpenCL中,提供了两种数据同步机制(mechanism):
  1. 锁(Locks):在一个资源被访问的时候,禁止其他访问;
  2. 栅栏(Barriers):在一个运行点中进行等待,直到所有运行任务都完成;(典型的BSP编程模型就是这样)

(1)shared memory

当任务要访问同一个数据时,最简单的方法就是共享存储shared memory(很多不同层面与功能的系统都有用到这个方法),大部分多核系统都支持这一模型。shared memory可以用于任务间通信,可以用flag或者互斥锁等方法进行数据保护,它的优缺点:
  1. 优点:易于实现,编程人员不用管理数据搬移;
  2. 缺点:多个任务访问同一个存储器,控制起来就会比较复杂,降低了互联速度,扩展性也比较不好。



(2)message passing
数据同步的另外一种模型是消息传递模型,可以在同一器件中,或者多个数量的器件中进行并发任务通信,且只在需要同步时才启动。
  1. 优点:理论上可以在任意多的设备中运行,扩展性好;
  2. 缺点:程序员需要显示地控制通信,开发有一定的难度;发送和接受数据依赖于库方法,因此可移植性差。

OpenCL并行执行内核

opencl可以有很多工作条目work-item,每一个item都有一个id,类似于线程的概念;看下面的例子:

左边是一般的编程写法,对数组元素递增;右边是opencl的写法,建立N个独立的work item,并行执行。这是最典型的opencl编程模型,用于数据并行任务,那么在真实的硬件中,又是如何完成并行任务的呢?实际上,这一块并不由opencl管,因为opencl只是一个编程标准,它提供了统一的编程接口和模型,而真正实现这些并行功能的是硬件支持厂商。比如intel对于CPU,NVIDIA对于GPU,Altera对于FPGA。正是因为有了opencl,才使得跨平台和跨硬件体系结构编程的可移植性成为可能。

由于性能是opencl编程的核心,而不是易用性,因此编程人员需要找到算法本身的并行部分,用kernel的方式来实现它们。工作条目就是一个最小的执行单元,工作条目可以组成工作组(work group)。这样的划分也与存储器有关,在opencl中,存储分为三大类:Global memory,Local memory,以及Private
memory。Global是可以让所有的工作组和工作条目都可见,Local是只有当前工作组中的工作条目可见,而Private是只有单独一个工作条目可见。这样的存储访问控制,可以有效利用高速缓存提高效率,而不是每一次数据访问都需要外部DDR。

来简单看看GPU和FPGA的实现架构,GPU的体系结构是高度并行的,高级的GPU有非常多的运算单元,有很高的存储器总线,较高的吞吐量,但是存储访问的延迟也比较大。因此针对GPU的程序设计,存储器的管理和访问是很关键的。GPU一般有小容量高速缓存,并使用PCIe与主机进行通信(当然,现在也有一些新的技术不用PCIe)。见下图:

而FPGA是针对定制硬件进行设计,并行度非常高,现代FPGA通常有上百万个逻辑单元,每一个单元可以实现一个逻辑功能;有数千个片内存储器模块,用于快速访问数据;有数千个专用DSP模块,用于加速计算数学函数(比如浮点乘法)。如下图:

当面向FPGA编译opencl时,执行不受固定数据通路和寄存器限制,实际上是根据运算把逻辑组织到函数单元中,然后将其连接起来形成专用的数据通路,实现特殊的内核功能,如下图

针对FPGA的opencl编程,大致有两种形式,一种是辅助加速器,软件在CPU中实现,使用FPGA来加速某些模块的运算,CPU和FPGA采用PCIe连接;另一种是SOC的方式,CPU是内嵌在FPGA版上的,这样的方式可以减小通信延迟:

到这里,对于opencl的并行编程大概有个了解了。我们先看一下opencl编程以及运行在FPGA和CPU上的大致流程,具体的过程会在后面的章节中描述,这里看个大概:

需要有两种编译器,一个是标准的C编译器,一个是opencl的编译器(因为我参考的资料是altera的,所以是altera的opencl编译器)。opencl编译器会生成比特流文件,下载到FPGA板上,然后host程序运行调用,通过PCIe连接在FPGA上启动内核执行。编译器会将整个电路构建完成,包括了算法逻辑,存储器结构,存储器访问控制与通路,内核主机间的通路等。如下图

最后比较一下各种硬件形态的开发效率与执行效率,而opencl在FPGA上作用就是绿色箭头的方向。

OpenCL学习笔记(二):并行编程概念理解的更多相关文章

  1. 大数据学习笔记3 - 并行编程模型MapReduce

    分布式并行编程用于解决大规模数据的高效处理问题.分布式程序运行在大规模计算机集群上,集群中计算机并行执行大规模数据处理任务,从而获得海量计算能力. MapReduce是一种并行编程模型,用于大规模数据 ...

  2. Android学习笔记二:activity的理解

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/7513290.html 一:activity定义了app的页面 一个app有很多个页面组成,一个页面其实就是一个 ...

  3. Clojure学习笔记(二)——函数式编程

    定义 “函数式编程”是一种编程范式(programming paradigm),即如何编写程序的方法论.主要思想是把运算过程尽量写成一系列嵌套的函数调用. 举例来说,现在有这样一个数学表达式: (1 ...

  4. spring in action 学习笔记二:aop的理解

    一: aop的思想的来在哪里? 一个系统一般情况下由多个组件组成,而每一个组件除了干自己的本职工作以外,有时还会干一些杂活(如:日志(logging).事务管理(transaction manager ...

  5. Java IO学习笔记二

    Java IO学习笔记二 流的概念 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成. 程序中的输入输 ...

  6. 学习笔记(二)--->《Java 8编程官方参考教程(第9版).pdf》:第七章到九章学习笔记

    注:本文声明事项. 本博文整理者:刘军 本博文出自于: <Java8 编程官方参考教程>一书 声明:1:转载请标注出处.本文不得作为商业活动.若有违本之,则本人不负法律责任.违法者自负一切 ...

  7. 孙鑫VC学习笔记:多线程编程

    孙鑫VC学习笔记:多线程编程 SkySeraph Dec 11st 2010  HQU Email:zgzhaobo@gmail.com    QQ:452728574 Latest Modified ...

  8. .NET Remoting学习笔记(一)概念

    目录 .NET Remoting学习笔记(一)概念 .NET Remoting学习笔记(二)激活方式 .NET Remoting学习笔记(三)信道 背景 自接触编程以来,一直听过这个名词Remotin ...

  9. 【转载】.NET Remoting学习笔记(一)概念

    目录 .NET Remoting学习笔记(一)概念 .NET Remoting学习笔记(二)激活方式 .NET Remoting学习笔记(三)信道 背景 自接触编程以来,一直听过这个名词Remotin ...

随机推荐

  1. React属性用法总结

    1. 键值对 <ClaaNameA name = “Tom” /> <ClaaNameA name = {Tom} /> <ClaaNameA name = {“Tom” ...

  2. React的this.props.children

    this.props用来获取组件从外部传入的属性,但是this.props.children比较特殊,它是由React给添加上的,表示组件的所有子节点.this.props.children可以用来读 ...

  3. bzoj1010: [HNOI2008]玩具装箱toy(斜率优化DP)

    Orz CYC帮我纠正了个错误.斜率优化并不需要决策单调性,只需要斜率式右边的式子单调就可以了 codevs也有这题,伪·双倍经验233 首先朴素DP方程很容易看出:f[i]=min(f[j]+(i- ...

  4. Indexing GROUP BY

    SQL databases use two entirely different group by algorithms. The first one, the hash algorithm, agg ...

  5. HDU2444 :The Accomodation of Students(二分图染色+二分图匹配)

    The Accomodation of Students Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  6. LruCache:从网络加载图片缓存实例

    OOM异常 堆内存用于存储实例对象,当程序不断创建对象,并且对象都有引用指向,那么垃圾回收机制就不会清理这些对象,当对象多到挤满堆内存的上限后,就产生OOM异常.Android系统为每个应用程序使用的 ...

  7. 手脱ASProtect v1.23 RC1(有Stolen Code)

    1.载入PEID ASProtect v1.23 RC1 常见ASprotect版本壳: ASProtect 1.23 RC4 按shift+f9键26次后来到典型异常 ASProtect 1.31 ...

  8. 游戏编程入门之Bomb Catcher游戏

    首先是代码: MyDirectX.h: #pragma once //header file #define WIN32_EXTRA_LEAN #define DIRECTINPUT_VERSION ...

  9. poi-对于word的操作(二)

    poi对于word文本的底纹和下划线的样式的展现 package poi.test; import java.io.FileOutputStream; import java.math.BigInte ...

  10. 2017 济南综合班 Day 5

    毕业考试 (exam.cpp/c/pas) (1s/256M) 问题描述 快毕业了,Barry希望能通过期末的N门考试来顺利毕业.如果他的N门考试平均分能够达到V分,则他能够成功毕业.现在已知每门的分 ...