前言

  本文从使用 GPU 编程技术的角度来了解计算中并行实现的方法思路。

并行计算中需要考虑的三个重要问题

1. 同步问题

在操作系统原理的相关课程中我们学习过进程间的死锁问题,以及由于资源共享带来的临界资源问题等,这里不做累述。

  2. 并发度

有一些问题属于 “易并行” 问题:如矩阵乘法。在这类型问题中,各个运算单元输出的结果是相互独立的,这类问题能够得到很轻松的解决 (通常甚至调用几个类库就能搞定问题)。

然而,若各个运算单元之间有依赖关系,那问题就复杂了。在 CUDA 中,块内的通信通过共享内存来实现,而块间的通信,则只能通过全局内存。

CUDA 并行编程架构可以用网格 (GRID) 来形容:一个网格好比一只军队。网格被分成好多个块,这些块好比军队的每个部门 (后勤部,指挥部,通信部等)。每个块又分成好多个线程束,这些线程束好比部门内部的小分队,下图可帮助理解:

3. 局部性

在操作系统原理中,对局部性做过重点介绍,简单来说就是将之前访问过的数据 (时间局部性) 和之前访问过的数据的附近数据 (空间局部性) 保存在缓存中。

在 GPU 编程中,局部性也是非常重要的,这体现在要计算的数据应当在计算之前尽可能的一次性的送进显存,在迭代的过程中一定要尽可能减少数据在内存和显存之间的传输,实际项目中发现这点十分重要的。

对于 GPU 编程来说,需要程序猿自己去管理内存,或者换句话来说,自己实现局部性。

并行计算的两种类型

1. 基于任务的并行处理

这种并行模式将计算任务拆分成若干个小的但不同的任务,如有的运算单元负责取数,有的运算单元负责计算,有的负责...... 这样一个大的任务可以组成一道流水线。

需要注意的是流水线的效率瓶颈在于其中效率最低的那个计算单元。

  2. 基于数据的并行处理

这种并行模式将数据分解为多个部分,让多个运算单元分别去计算这些小块的数据,最后再将其汇总起来。

一般来说,CPU 的多线程编程偏向于第一种并行模式,GPU 并行编程模式则偏向于第二种。

常见的并行优化对象

1. 循环

这也是最常见的一种模式,让每个线程处理循环中的一个或一组数据。

这种类型的优化一定要小心各个运算单元,以及每个运算单元何其自身上一次迭代结果的依赖性。

2. 派生/汇集模式

该模式下大多数是串行代码,但代码中的某一段可以并行处理。

典型的情况就是某个输入队列当串行处理到某个时刻,需要对其中不同部分进行不同处理,这样就可以划分成多个计算单元对改队列进行处理 (也即派生),最后再将其汇总 (也即汇集)。

这种模式常用于并发事件事先不定的情况,具有 “动态并行性”。

3. 分条/分块模式

对于特别庞大的数据 (如气候模型),可以将数据分为过个块来进行并行计算。

4. 分而治之

绝大多数的递归算法,比如快速排序,都可以转换为迭代模型,而迭代模型又能映射到 GPU 编程模型上。

特别说明:虽然费米架构和开普勒架构的 GPU 都支持缓冲栈,能够直接实现递归模型到 GPU 并行模型的转换。但为了程序的效率,在开发时间允许的情况下,我们最好还是先将其转换为迭代模型。

第二篇:从 GPU 的角度理解并行计算的更多相关文章

  1. 转:如何学习SQL(第二部分:从关系角度理解SQL)

    转自:http://blog.163.com/mig3719@126/blog/static/285720652010950825538/ 6. 从关系角度理解SQL 6.1. 关系和表 众所周知,我 ...

  2. OpenStack学习系列-----第二篇 由一个错误看理解整个架构的重要性

    看了openstack没几天,然后就开始试着用Java调用所有的API,第一步得到Credentials的时候成功了,然后第二步,传参数使所有的server信息都列出来的时候报错404.具体描述如下( ...

  3. 图解并发与并行-分别从CPU和线程的角度理解

    本文作为图解java并发编程的第三篇,前2篇访问地址如下所示: 图解进程线程.互斥锁与信号量-看完还不懂你来打我 8成以上的java线程状态图都画错了--图解java并发第二篇 一.CPU角度的并发与 ...

  4. 深入理解javascript对象系列第二篇——属性操作

    × 目录 [1]查询 [2]设置 [3]删除[4]继承 前面的话 对于对象来说,属性操作是绕不开的话题.类似于“增删改查”的基本操作,属性操作分为属性查询.属性设置.属性删除,还包括属性继承.本文是对 ...

  5. 深入理解javascript函数系列第二篇——函数参数

    × 目录 [1]arguments [2]内部属性 [3]函数重载[4]参数传递 前面的话 javascript函数的参数与大多数其他语言的函数的参数有所不同.函数不介意传递进来多少个参数,也不在乎传 ...

  6. 深入理解javascript作用域系列第二篇——词法作用域和动态作用域

    × 目录 [1]词法 [2]动态 前面的话 大多数时候,我们对作用域产生混乱的主要原因是分不清楚应该按照函数位置的嵌套顺序,还是按照函数的调用顺序进行变量查找.再加上this机制的干扰,使得变量查找极 ...

  7. 深入理解javascript作用域系列第二篇

    前面的话 大多数时候,我们对作用域产生混乱的主要原因是分不清楚应该按照函数位置的嵌套顺序,还是按照函数的调用顺序进行变量查找.再加上this机制的干扰,使得变量查找极易出错.这实际上是由两种作用域工作 ...

  8. 视觉SLAM中的数学基础 第二篇 四元数

    视觉SLAM中的数学基础 第二篇 四元数 什么是四元数 相比欧拉角,四元数(Quaternion)则是一种紧凑.易于迭代.又不会出现奇异值的表示方法.它在程序中广为使用,例如ROS和几个著名的SLAM ...

  9. 第二篇 界面开发 (Android学习笔记)

    第二篇 界面开发 第5章 探索界面UI元素 ●The Android View Class     ●△Widget设计步骤 需要修改三个XML,以及一个class: 1)第一个xml是布局XML文件 ...

随机推荐

  1. PDF抽取文字 C# with Adobe API

    前提是PDF里面是有文字的! 一次性取得所有页内容: /// <summary> /// 改进前取得所有页的所有word /// </summary> /// <para ...

  2. bzoj 1305: [CQOI2009]dance 二分+網絡流判定

    1305: [CQOI2009]dance跳舞 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 1340  Solved: 581[Submit][Sta ...

  3. js中常用framesetiframe页面跳转传参方法实例大全

    logf的空间

  4. Android开源项目发现--- 工具类向下兼容篇(持续更新)

    1. ActionBarSherlock 为Android所有版本提供统一的ActionBar,解决4.0以下ActionBar的适配问题 项目地址:https://github.com/JakeWh ...

  5. 14.6.8 Configuring the InnoDB Master Thread IO Rate 配置InnoDB 主线程IO 速率:

    14.6.8 Configuring the InnoDB Master Thread IO Rate 配置InnoDB 主线程IO 速率: 主线程 在InnoDB 是一个线程 执行各种任务在后台. ...

  6. ping详解

    Linux系统的ping命令是常用的网络命令,它通常用来测试与目标主机的连通性,我们经常会说“ping一下某机器,看是不是开着”.不能打开网页时会说“你先ping网关地址192.168.1.1试试”. ...

  7. 协定类型不具有 ServiceContractAttribute 特性

    协定类型 ZBMService.QueryHistoryData 不具有 ServiceContractAttribute 特性.若要定义有效协定,指定的类型(协定接口或服务类)必须具有 Servic ...

  8. [LeetCode#191]Number of Bits

    Problem: Write a function that takes an unsigned integer and returns the number of ’1' bits it has ( ...

  9. HDU --3549

    Flow Problem Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tota ...

  10. Python根据上下限生成不重复随机数1

    Python 2.7.5代码: #coding=utf-8 import random #定义计数器,默认为0 num=0 #定义随机结果集,默认为空列表 choose_resault=[] #最多可 ...