(CUDA 编程8).CUDA 内存使用 global 二------GPU的革命
2012-07-29 09:12
351 查看
(CUDA 编程8).CUDA 内存使用 global 二------GPU的革命
作者:赵开勇 来源:http://www.hpctech.com/2009/0818/206.html
8. CUDA 内存使用 global 二------GPU的革命
序言:最近在另一个不写技术的blog上,写了最近的一些事情,或许是释怀以后才会把心理面的事情写出来,很感谢很多朋友能理解我现在的心情,有的朋友也会感到很惊讶,平时
8. CUDA 内存使用 global 二------GPU的革命前面一章节已经写到了内存访问的问题,内存对齐的问题,不过在看到编程手册第五章的时候,还是会有很多朋友问到我关于CUDA的global内存访问的问题,怎么是访问的冲突,怎样才能更好的访问内存,达到更高的速度。下面先看几张图,这些图都是CUDA编程手册上的图,然后分别对这些图做解释,来理解硬件1.0,1.1
以及现在最新的硬件的访问内存的区别。
我们在这里再深入的讲解一下global内存对齐的问题,每次执行一条明命令的时候,都是会按照32个thread为一个warp,一起来执行,但是在执行的时候,又会按照硬件的条件(这里有两个限制条件,一个是内存访问的时钟和执行core的时钟不一样,第二个是为了细粒度的分支的问题)然后就会把16个thread组成的half-warp来一次访问global内存才能让访问内存的性能高一些,这个可以理解;
就像手册上说的那样,如果16个thread(half-warp)访问内存的时候,如果每一个thread访问32bits就是4个字节,那么就可以合并为一个64bytes的访问,手册上这点写得有点让人咋一看不太明白~4bytes(32bits)*16
= 64bytes,就是这么来的,如果每一个thread访问64bits(8个bytes),那么就可以合并为128bytes的访问;这里啦,由于合并访问的最大限制是128bytes,所以最大也按照128bytes一次访问来合并,如果超过,就得多次访问,或者如果没有按照这样的方式对齐访问,也会多次访问;下面是1.2device之前的访问的几个图,这里要把1.2device以前和以后的分开,是因为这里在对齐访问的方式的时候,有不同的策略;先看1.2device以前的能合并为一次访问的情况:
下图是编程手册上的图:
这里的每一个thread都是访问的对应的地址,是对齐的,所以可以合并为一个存储event;
下面这个图是没有对齐访问,就造成了non-coalesced访问的问题,下面可以看图说话:
左边的那个好理解,中间对应的thread访问的地址交叉了,thread3和thread4交叉访问了,在硬件1.2版本之前的都会造成Non-Coalesced访问;
详细的需要说明的是右边的为什么也造成了Non-Coalesced(非对齐)访问,这个是基础问题,大家理解的内存对齐是怎么样的?按照固定思路,或者教材上强调的都是中间过程的内存访问的对齐,但是内存是从offset 0x00000000位置开始的,就是偏移量0开始的,如果要真的满足内存对齐,严格的说起来就需要从内存的0地址开始算起,再加上我们知道的global内存的对齐方式有几种,4位bytes,8bytes,16bytes,这里说的对齐方式,注意区别关系;再来看看右边的那个图:thread0开始,从address128的位置开始向下便宜的位置是?132-128=4
偏移了4,16个threads整体访问的是16*4=64,是从132开始的,从0算起来,132-0 =132; 132/16 = 8…4,从整体上讲,从0偏移位置开始,偏移了4个位置,这里的就造成了访问的未对齐,这个是从整体角度上讲的,和左边的图比较一下,那个是按照局部对齐来说的,注意理解;
继续看图说话:
左边的图看看,算一下,局部的时候偏移了,从局部和整体来说,都会引起未对齐访问;
右边的图自己算一下,是不是超出了刚才我说的范围;所以造成了内存访问的未对齐情况;
前面我们看的图都是1.2版本前的硬件的情况下的内存访问情况,现在看看1.2版本以后的硬件;
这里解释一下,什么叫1.2版本的硬件,或许有些朋友也不太了解,g80架构的都是1.0或者1.1的硬件架构,现在的gtx200系列的都是1.3的架构,其实1.2的硬件架构,或许是Nvidia的一个内部的,没有推出产品,可能准备提供给低端的产品,但是我想没有推出低端的产品,直接就上1.3device了,市场需求吧~~如果下一步GTX的架构还是按照老路子,不改进的话,或许Intel的Lrb上来以后,对Nvidia的产品,就是一个很大的竞争了;
不说废话了,先看图:
1.2以后的硬件版本,弱化了threads之间交叉访问的时候,没对齐的情况,只要大家都在一次访问的64bytes的一个段里面,或者128bytes的一个段里面面,这样的段访问,那就可以不用多次访问,当然如果你16个threads分别跨过了16个段,那就得产生16个存储event~记住几个段的定义,这里说的段,就是我们常常理解的对齐的方式,全局的内存访问对齐方式,8个bits的是按照32bytes对齐,16bits的是按照64bytes对齐,32bits和64bits都是按照128bytes对齐;
在优化代码的时候,这个地方是一个值得注意的部分;
API函数里面有对齐访问的接口,会按照对齐的方式分配global内存给你,不过注意其中的一个offset值的使用,这个是为了解决全局情况下的对齐偏移的问题:)cudaMallocPitch,这个函数,注意使用~
相关文章推荐
- (CUDA 编程9).CUDA shared memory使用------GPU的革命
- (CUDA 编程10).CUDA cosnstant使用(一)------GPU的革命
- 8. CUDA 内存使用 global 二------GPU的革命
- CUDA 编程1).CUDA 线程执行模型分析(一)招兵 ------ GPU的革命(转)
- GPU CUDA常量内存使用
- 使用GPU进行字符串匹配--cuda编程实现
- 《GPU高性能编程-CUDA实战》中例子头文件使用
- 《GPU高性能编程-CUDA实战》中例子头文件使用 (2012-12-25 20:45:48)
- (CUDA 编程1).CUDA 线程执行模型分析(一)招兵 ------ GPU的革命
- 7. CUDA内存访问(一)提高篇------按部就班 ------GPU的革命
- CUDA GPU编程中使用结构体传递函数参数
- CUDA编程接口(一)------一十八般武器------GPU的革命 推荐
- 9. CUDA shared memory使用------GPU的革命
- Linux进程间通信(IPC)编程实践(七)共享内存的使用-System V共享内存(API)
- CUDA硬件实现分析(一)------安营扎寨-----GPU的革命
- 使用OpenCV的GPU模块(Win7x64+VS2010+OpenCV2.4.5+CUDA5.0)配置详解
- C专家编程精华第二篇----C对内存的使用,底层探索
- 【Cuda并行编程之二】Cuda Memory Hierarchy_Cuda内存层次结构
- 高性能网络编程7--tcp连接的内存使用
- 提高多GPU编程与执行效率 CUDA 4.0初探