四 GPU 并行编程的存储系统架构
前言
在用 CUDA 对 GPU 进行并行编程的过程中,除了需要对线程架构要有深刻的认识外,也需要对存储系统架构有深入的了解。
这两个部分是 GPU 编程中最为基础,也是最为重要的部分,需要花时间去理解吸收,加深内功。
了解 GPU 存储系统架构的意义
CUDA 编程架构的设计思路本身也就是让程序员去使用缓存,而不是让缓存像 CPU 编程结构那样对程序员透明。
通过对所使用存储结构的优化,能够让程序的并行后的效果得到很大提高。
因此,这个问题是需要我们在开发全程中考虑的。
第一层:寄存器
每个流处理器中的寄存器数以千计,每个线程都能分配到其私有的寄存器,这样做的好处是使得线程的切换几乎是零开销 (也许说是线程束的切换会更为准确)。
应当在硬件条件允许的情况下,尽可能地使用寄存器 (注意是硬件条件的允许之下)。
在核函数中定义的变量就是寄存器变量。
第二层:共享内存
共享内存的本质是可受用户控制的一级缓存。每个 SM 中的一级缓存与共享内存共享一个 64 KB的内存段。在费米架构中,可以为每个块定义 16 KB的共享内存。灵活地使用共享内存,能够大幅度提高显存的带宽。此外,共享内存也是实现块内线程间通信的有效工具。
使用时需要注意的一个地方是,只有在确定需要重复利用此空间的数据,或者明确要使块内线程进行通信的前提下,才考虑使用共享内存。(原因不解释)
使用时需要注意的另一个地方是应当尽可能地避免存储体冲突。这里所谓的存储体是指实现共享内存的硬件 - 一个费米架构的设备上有 32 个存储体。解决此问题的关键在于:顺序访问存储体。
实际开发中,常常将一个任务分解成多个部分(不论是任务分解还是数据分解),共享内存在其中扮演着任务块工作任务汇总或者数据块工作任务汇总的角色。
核函数中定义的变量加上__shared__声明后就会存放在共享内存中了。
第三层:常量内存
常量内存其实只是全局内存的一种虚拟地址形式,并没有特殊保留的常量内存块。
使用起来非常方便,在主机端对需要放到常量内存区的变量添加 __constant__ 关键字声明之即可。
唯独需要注意的是,如果一个常量仅仅是一个字面值,那么将它声明为宏也行,例如 PI 这样的常数就一般定义为宏。
第四层:全局内存
全局内存,也就是显存。
在主机端开辟的显存空间均属于全局内存范畴。
使用全局内存的时候,需要注意的是应当学会对显存采取合并的访问方式。何谓合并的访问方式呢?请参阅下篇文章。
四 GPU 并行编程的存储系统架构的更多相关文章
- 第四篇:GPU 并行编程的存储系统架构
前言 在用 CUDA 对 GPU 进行并行编程的过程中,除了需要对线程架构要有深刻的认识外,也需要对存储系统架构有深入的了解. 这两个部分是 GPU 编程中最为基础,也是最为重要的部分,需要花时间去理 ...
- 三 GPU 并行编程的运算架构
前言 GPU 是如何实现并行的?它实现的方式较之 CPU 的多线程又有什么分别?本文将做一个较为细致的分析. GPU 并行计算架构 GPU 并行编程的核心在于线程,一个线程就是程序中的一个单一指令流, ...
- 第三篇:GPU 并行编程的运算架构
前言 GPU 是如何实现并行的?它实现的方式较之 CPU 的多线程又有什么分别? 本文将做一个较为细致的分析. GPU 并行计算架构 GPU 并行编程的核心在于线程,一个线程就是程序中的一个单一指令流 ...
- 五 浅谈CPU 并行编程和 GPU 并行编程的区别
前言 CPU 的并行编程技术,也是高性能计算中的热点,也是今后要努力学习的方向.那么它和 GPU 并行编程有何区别呢? 本文将做出详细的对比,分析各自的特点,为将来深入学习 CPU 并行编程技术打下铺 ...
- 第五篇:浅谈CPU 并行编程和 GPU 并行编程的区别
前言 CPU 的并行编程技术,也是高性能计算中的热点,也是今后要努力学习的方向.那么它和 GPU 并行编程有何区别呢? 本文将做出详细的对比,分析各自的特点,为将来深入学习 CPU 并行编程技术打下铺 ...
- 四、并行编程 - 并行LINQ(PLINQ) 的使用。AsParallel
用于对内存中的数据做并行运算,也就是说其只支持 LINQ to Object 的并行运算 一.AsParallel(并行化) 就是在集合后加个AsParallel(). 例如: , ); == ); ...
- 【并行计算-CUDA开发】GPU并行编程方法
转载自:http://blog.sina.com.cn/s/blog_a43b3cf2010157ph.html 编写利用GPU加速的并行程序有多种方法,归纳起来有三种: 1. 利用现有的G ...
- GPU并行编程小结
http://peghoty.blog.163.com/blog/static/493464092013016113254852/ http://blog.csdn.net/augusdi/artic ...
- GPU并行编程:内核及函数的实现
原文链接 回想一下我们之前在设备上使用“kernelFunction<<<1,1>>>(..)”执行一个函数的代码,我在那里还曾说过后面会细说,本文就详细介绍一下参 ...
随机推荐
- 在 Ubuntu 14.04/15.04 上配置 Node JS v4.0.0
大家好,Node.JS 4.0 发布了,这个流行的服务器端 JS 平台合并了 Node.js 和 io.js 的代码,4.0 版就是这两个项目结合的产物——现在合并为一个代码库.这次最主要的变化是 N ...
- elasticsearch插件之一:kibana
介绍: 要说kibana,就不得不先说一下logstash.这里呢,先要讲个故事.故事是开头是这样的,Logstash早期曾经自带了一个特别简单的logstash-web用来查看ES中的数据,其功能太 ...
- 使用read write 读写socket
一旦,我们建立好了tcp连接之后,我们就可以把得到的fd当作文件描述符来使用. 由此网络程序里最基本的函数就是read和write函数了. 写函数: ssize_t write(int fd, con ...
- ios 常用的小框架
在ios开发中,一些请求 kvc 下拉列表 图片请求等等自己手写代码的话非常麻烦,还容易出现一系列的问题,现在整理了一些常用的一些小框架. 其中MJExtension 和 MJRefresh 这两个 ...
- static关键字的理解
#include<stdio.h> int counter(int i){ static int count=0;//编译时只运行一次 count=count+i; return coun ...
- 记一个有想法却没能力实现的硬件产品——mp3校时闹钟
枕头旁的闹钟,我想大家都用过,很便宜.用一节干电池供电.但其最大的缺点就是不太准,不能校时. 电池啥事用光,也不知道.钟是走的很慢,没按时闹,搞的自己迟了到. 于是就有了我的漫长思考过程... 先说手 ...
- DotNetBar v14.0.0.3 Fully Cracked
更新信息: http://www.devcomponents.com/customeronly/releasenotes.asp?p=dnbwf&v=14.0.0.3 如果遇到破解问题可以与我 ...
- oracle触发器的小例子
实现功能: 插入数据前触发,检查与插入数据几个属性相同的在表中的列将状态改为false,再执行插入. 解决方案: CREATE OR REPLACE TRIGGER tri_insert BEFORE ...
- 基于反射的通过set方法的依赖注入,可以看成一种设计模式,自己来用
非常好用,在properties文件中配置字符串和类名之间的对应,在程序里读取文件,找到类名,通过反射,达到调用set方法的目的,然后直接将自己的指向其他类的对象的引用赋值,指向实体对象. 比如use ...
- python 接口开发(一)
cmd中,提示pip版本太低,先升级pip pip install --upgrade pip (pip,安装和管理python扩展包的工具) cmd下,pip,出现详细信息证明装成功了 pip ...