转自:http://blog.sina.com.cn/s/blog_48b9e1f90100fm5f.html

结合lec07_intro_cuda.pptx学习

内存类型

CGMA: Compute to Global Memory Access ratio

Constant memory只允许device只读,比global memory 能够提供更快更多的并行数据访问路径给kernel。

Register和local memory是线程私有的。Shared memory是同一个block中的线程共享的。

Table 1显示了cuda声明变量的语法。Scope表示变量能够被访问的线程范围。包括thread:线程单独访问,每个thread都有一个变量,如果kernel声明一个scope为thread的变量y,在启动x个线程后,就会有x个版本的变量y。block:被block中的所有thread访问,grid:被grid中的所有线程访问。

Lifetime是变量的生存期。注意:如果生存期为kernel,那么在kernel不同的启动之间,变量的值是不会被保存下来的。每次启动一次kernel都要对变量进行初始化。生存期为application的变量,必须在所有函数体外进行声明,变量可以在程序执行中保存下来并可以被所有kernel访问。

非数组自动变量:除了在kernel和device函数中声明的数组外,其他所有自动变量都在寄存器中。这些变量称为scalar变量,scope是单独的线程。当一个kernel声明了一个自动变量,系统会为执行这个kernel函数的所有线程copy这个变量。线程终止后,所有变量也就不存在了。

自动数组变量:存在global memory中,对它们的访问需要长延迟。他们的scope也是单独的线程。因此,对这种变量尽量避免使用。

(__device__)__shared__修饰的变量,表示CUDA中的共享变量。共享变量的scope是block,block中的所有线程都可以看到共享变量的同一个版本。Lifetime是kernel,kernel结束,共享变量内存也就不存在了。对共享内存的访问非常快而且是高度并行的。CUDA编程者通常用共享内存来保留一部分在kernel中用的多的全局内存数据。

(__device__) __constant__修饰的变量表示常数变量constant variable。Constant variable必须在函数体外进行声明。Scope是grids, lifetime是整个应用程序的执行。Constant variable常用于为kernel function提供输入值,存储在global memory中但被cached。一个程序constant variable最大可以使65536个字节。

__device__修饰的变量是global variable,存储在global memory中。对global memory的访问非常慢。由于global variable对所有kernel中的所有线程都是可见的。因此,global variable可以作为跨block的线程之间的协同方法。但是,如果不终止目前的kernel,无法保证线程之间数据的一致性。因此,global variable通常作为kernel function之间的信息传递。

指针只能用于指向global memory的数据对象,不用于device memory。指针有两种典型用法:第一,如果一个对象由host function分配,指向此对象的指针被cudaMalloc()初始化并能够作为参数传递给kernel function。第二,在global memory中声明的变量的地址可以分配给一个指针变量。例如,

float * ptr=&GlobalVar。

减少全局内存通信的策略

       由于全局内存大而慢,共享内存小而快。常用的策略是把数据划分成片tile,每一片适合共享内存的使用。对这些tile的kernel计算可以独立的进行。

__global__ void MatrixMulKernel(float* Md, float* Nd, float* Pd, int Width)

{

1. __shared__float Mds[TILE_WIDTH][TILE_WIDTH];

2. __shared__float Nds[TILE_WIDTH][TILE_WIDTH];

3. int bx = blockIdx.x; int by = blockIdx.y;

4. int tx = threadIdx.x; int ty = threadIdx.y;

// Identify the row and column of the Pd element to work on

5. int Row = by * TILE_WIDTH + ty;

6. int Col = bx * TILE_WIDTH + tx;

7. float Pvalue = 0;

// Loop over the Md and Nd tiles required to compute the Pd element

8. for (int m = 0; m < Width/TILE_WIDTH; ++m) {

// Coolaborative loading of Md and Nd tiles into shared memory

9.           Mds[ty][tx] = Md[Row][m*TILE_WIDTH + tx];

10.          Nds[ty][tx] = Nd[m*TILE_WIDTH + ty][Col];

11.         __Syncthreads();

12.         for (int k = 0; k < TILE_WIDTH; ++k)

13.                Pvalue += Mds[ty][k] * Nds[k][tx];

14. }

15. Pd[Row][Col] = Pvalue;

}

硬件限制:

GeForce 8800GTX每个SM有8K个寄存器,整个处理器有128K个寄存器。一个SM最多有768个线程。如果要达到这个线程最大数,每个线程只能用8K/768=10个寄存器。如果每个线程要用11个寄存器,那么线程数就会减少。例如,如果一个block有256个线程,那么每个SM中只有1/3的线程同时存在。

共享内存也会限制线程数目。在GeForce 8800 GTX中,每个SM有16K bytes大小的共享内存。而共享内存是block使用的。每个SM最多有8个block,所以,如果一个SM中有8个block,那么每个block最多能够使用2K字节的共享内存。以矩阵乘为例,若tile大小为16*16,那么,每个block需要16*16*4=1K字节存储Mds,需要1K字节存储Nds。因此,一个block需要2K字节的共享内存。根据共享内存16K 字节的限制,最多有8个block可以同时存在于一个SM中,这也是硬件限制上的最大block数目了。若tile size是32*32,那么每个block需要8K 字节共享内存,那么一个SM只能有2个block。

注意:不时关注CUDA主页,关注CUDA相关的最新研究

http://www.nvidia.com/object/cuda_home.html#

CUDA学习笔记(三)——CUDA内存的更多相关文章

  1. CUDA学习笔记-1: CUDA编程概览

    1.GPU编程模型及基本步骤 cuda程序的基本步骤如下: 在cpu中初始化数据 将输入transfer到GPU中 利用分配好的grid和block启动kernel函数 将计算结果transfer到C ...

  2. 操作系统学习笔记(三) windows内存管理

    //系统物理页面是由 (Page Frame Number Database )简称PFN数据库来进行管理,实际上是一个数组,每个物理页面都对应一个PFN项. 进程的地址空间是通过VAD(Virtua ...

  3. iOS学习笔记之ARC内存管理

    iOS学习笔记之ARC内存管理 写在前面 ARC(Automatic Reference Counting),自动引用计数,是iOS中采用的一种内存管理方式. 指针变量与对象所有权 指针变量暗含了对其 ...

  4. java之jvm学习笔记三(Class文件检验器)

    java之jvm学习笔记三(Class文件检验器) 前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验,这就是今天的学习主题,cl ...

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

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

  6. Java IO学习笔记三:MMAP与RandomAccessFile

    作者:Grey 原文地址:Java IO学习笔记三:MMAP与RandomAccessFile 关于RandomAccessFile 相较于前面提到的BufferedReader/Writer和Fil ...

  7. Oracle学习笔记三 SQL命令

    SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)  

  8. [Firefly引擎][学习笔记三][已完结]所需模块封装

    原地址:http://www.9miao.com/question-15-54671.html 学习笔记一传送门学习笔记二传送门 学习笔记三导读:        笔记三主要就是各个模块的封装了,这里贴 ...

  9. JSP学习笔记(三):简单的Tomcat Web服务器

    注意:每次对Tomcat配置文件进行修改后,必须重启Tomcat 在E盘的DATA文件夹中创建TomcatDemo文件夹,并将Tomcat安装路径下的webapps/ROOT中的WEB-INF文件夹复 ...

  10. VSTO学习笔记(三) 开发Office 2010 64位COM加载项

    原文:VSTO学习笔记(三) 开发Office 2010 64位COM加载项 一.加载项简介 Office提供了多种用于扩展Office应用程序功能的模式,常见的有: 1.Office 自动化程序(A ...

随机推荐

  1. document.body.scrollTop 各浏览器兼容性解决

    document.compatMode:获取当前浏览器采用的渲染方式.主要是浏览器的模式,有两个:BackCompat,CSS1Compat.其中前者是怪异模式,后者是标准模式. IE默认是BackC ...

  2. 洛谷P1417 烹调方案

    题目背景 由于你的帮助,火星只遭受了最小的损失.但gw懒得重建家园了,就造了一艘飞船飞向遥远的earth星.不过飞船飞到一半,gw发现了一个很严重的问题:肚子饿了~ gw还是会做饭的,于是拿出了储藏的 ...

  3. (Beta)Let's-版本发布说明

      Let's App(Beta)现已隆重上市   GIT源码请戳此处 版本的新功能 我们在这一版本对于项目的规划目标主要集中在三个方面——预约用户观感,完善功能链条,改善用户体验 界面 首先,在β阶 ...

  4. [Angularjs]视图和路由(一)

    写在前面 对单页应用来讲,视图和路由的作用可以从一个视图跳转到另外一个视图,可以合理管理用户在使用过程中看到的界面. 将视图分解成布局和模版视图,并且根据用户当前访问的URL来展示对应的视图,将会是一 ...

  5. Java创建目录 mkdir与mkdirs的区别

    两者的参数都是路径串,但: mkdir只能创建父目录存在的目录,而mkdirs不论要创建目录的父目录是否存在都能创建成功. 例如:假设目录c:/uses/zsm/desktop/dir1不存在,,现在 ...

  6. 利用SecureCRT上传、下载文件(使用sz与rz命令)

    sz用法: 下载一个文件 sz filename 下载多个文件 sz filename1 filename2 下载dir目录下的所有文件,不包含dir下的文件夹 sz dir/* 下载文件存放位置在s ...

  7. Linux(Ubuntu)下面SecureCRT 完全破解

    转载声明:本文来自http://www.boll.me/archives/680 相关说明: 上篇发了个Linux(Ubuntu) 下 SecureCRT 7 30天循环破解在启动的时候会多输入一次确 ...

  8. 保护隐私:清除cookie、禁用cookie确保安全【分享给身边的朋友吧】

    常在网上漂,隐私保不了.ytkah深有体会,某天搜索一个词,然后你就能在一些网站上看到这个词的相关广告,神奇吧?这就是你的浏览器cookie泄露了,或者更严重地说是你的隐私泄露了,可怕吧!搜索引擎通过 ...

  9. basic use of sidekiq

    参考页面 https://github.com/mperham/sidekiq https://github.com/mperham/sidekiq/wiki/Getting-Started 强烈推荐 ...

  10. 关于mac安装rails报错clang: error: unknown argument

    文章都是从我的个人博客上转载过来的,大家可以点击我的个人博客. www.iwangzheng.com mac上安装rails的时候报错, 安装rails的在终端执行了一句命令: $sudo gem i ...