cuda编程基础
转自: http://blog.csdn.net/augusdi/article/details/12529247
- CUDA编程模型将CPU作为主机,GPU作为协处理器(co-processor)或设备。在这个模型中,CPU负责逻辑性强的事务处理和串行计算,GPU则专注于高度线程化的并行处理任务。CPU、GPU各自拥有相互独立的存储器地址空间。
- 一旦确定了程序中的并行部分,就可以考虑把这部分计算工作交给GPU。
- kernel:运行在GPU上的C函数称为kernel。一个kernel函数并不是一个完整的程序,而是整个CUDA程序中的一个可以被并行执行的步骤。当调用时,通过N个不同的CUDA线程执行N次。
- 一个完整的CUDA程序是由一系列的设备端kernel函数并行步骤和主机端的串行处理步骤共同组成的。
- 一个kernel函数中存在两个层次的并行,即Grid中的block间并行和block中的thread间并行。
- 计算核心:GPU中有多个流多处理器(Stream Multiprocessor, SM),流多处理器即计算核心。每个流多处理器又包含8个标量流处理器(Stream Processor),以及少量的其他计算单元。SP 只是执行单元,并不是完整的处理核心。拥有完整前端的处理核心,必须包含取指、解码、分发逻辑和执行单元。隶属同一 SM 的8个 SP共用一套取指与射单元,也共用一块共享存储器。
- CUDA 中的 kernel 函数是以 block 为单元执行的,同一 block 中的线程需要共享数据,因此必须在同一个 SM 中发射,而 block 中的每一个 thread 则被送到一个 SP 上执行。
- 一个 block 必须被分配到一个 SM 中,但一个 SM 中同一时刻可以有多个活动线程块(active block)在等待执行,即在一个 SM 中可同时存在多个 block 的上下文。在一个 SM 中放入多个线程块是为了隐藏延迟(latency),更好地利用执行单元的资源。当一个 block 进行同步或访问显存等高延迟操作时,另一个 block 就可以“乘虚而入”,占用 GPU 执行资源。
- 限制 SM 中活动线程块数量的因素包括:SM中的活动线程块数量不超过 8 个;所有活动线程块中的 warp 数之和在计算能力 1.0/1.1 设备中不超过 24,在计算能力 1.2/1.3 设备中不超过 32;所有活动线程块使用的寄存器和存储器之和不超过 SM 中的资源限制。
- CUDA中以线程网格(Grid)的形式组织,每个线程网格由若干个线程块(block)组成,而每个线程块又由若干个线程(thread)组成。
- threadIdx:CUDA中使用了dim3类型的内建变量threadIdx和blockIdx。threadIdx是一个包含3个组件的向量,这样线程可以用一维、二维或三维线程索引进行识别,从而形成一个一维、二维或三维线程块。一个线程的索引和它的线程ID之间的关系非常直接:
- 对于一个一维的块,线程的threadIdx就是threadIdx.x;
- 对于一个二维的大小为(Dx,Dy)的块,线程的threadIdx就是(threadIdx.x + threadIdx.y * Dx);
- 对于一个三维的大小为(Dx,Dy,Dz)的块,线程的threadIdx是(threadIdx.x + threadIdx.y * Dx + threadIdx.z * Dx * Dy)。
- 一个block中的线程数量不能超过512个。
- 在同一个block中的线程可以进行数据通信。CUDA中实现block内通信的方法是:在同一个block中的线程通过共享存储器(shared memory)交换数据,并通过栅栏同步保证线程间能够正确地共享数据。具体来说,可以在kernel函数中需要同步的位置调用__syncthreads()函数。
- 一个block中的所有thread在一个时刻执行指令并不一定相同。例如,在一个block中可能存在这样的情况:有些线程已经执行到第20条指令,而这时其他的线程只执行到第8条指令的第21条语句的位置通过共享存储器共享数据,那么只执行到第8条语句的线程中的数据可能还没来得及更新,就被交给其他线程去处理了,这会导致错误的计算结构。而调用__syncthreads()函数进行栅栏同步(barrier)以后,就可以确保只有当block中的每个线程都运行到第21条指令以后,程序才会继续向下进行。
- 每个线程块中的线程数量、共享存储器大小和寄存器数量都要受到处理核心硬件资源的限制,其原因是:
- 在GPU中,共享存储器与执行单元的物理距离必须很小,处于同一个处理核心中,以使得共享存储器的延迟尽可能小,从而保证线程块中的各个线程能够有效协作。
- 为了在硬件上用很小的代价就能实现__syncthreads()函数,一个block中所有线程的数据都必须交由同一处理核心进行处理。
- 内核函数必须通过__global__函数类型限定符定义,并且只能在主机端代码中调用。在调用时,必须声明内核函数的执行参数。例如:
- // Define kernel
__global__ void VecAdd(float * A, float * B, float * C){int i = threadIdx.x;C[i] = A[i] + B[i];}int main{// Call kernelVecAdd<<<1, N>>>(A, B, C);}
- 必须先为Kernel中用到的数组或变量分配好足够的空间,再调用kernel函数。否则,在GPU计算时会发生错误。
- 在设备端运行的线程之间是并行执行的,其中的每个线程按指令的顺序串行执行一次kernel函数。每一个线程有自己的block ID和thread ID用于与其他线程相区分。block ID和thread ID只能在kernel中通过内建变量访问。内建变量是由设备中的专用寄存器提供的,是只读的,且只能在GPU端的kernel函数中调用。
cuda编程基础的更多相关文章
- CUDA编程
目录: 1.什么是CUDA 2.为什么要用到CUDA 3.CUDA环境搭建 4.第一个CUDA程序 5. CUDA编程 5.1. 基本概念 5.2. 线程层次结构 5.3. 存储器层次结构 5.4. ...
- CUDA编程-(1)Tesla服务器Kepler架构和万年的HelloWorld
结合CUDA范例精解以及CUDA并行编程.由于正在学习CUDA,CUDA用的比较多,因此翻译一些个人认为重点的章节和句子,作为学习,程序将通过NVIDIA K40服务器得出结果.如果想通过本书进行CU ...
- CUDA编程之快速入门
CUDA(Compute Unified Device Architecture)的中文全称为计算统一设备架构.做图像视觉领域的同学多多少少都会接触到CUDA,毕竟要做性能速度优化,CUDA是个很重要 ...
- CUDA编程(二) CUDA初始化与核函数
CUDA编程(二) CUDA初始化与核函数 CUDA初始化 在上一次中已经说过了,CUDA成功安装之后,新建一个project还是十分简单的,直接在新建项目的时候选择NVIDIA CUDA项目就能够了 ...
- CUDA编程之快速入门【转】
https://www.cnblogs.com/skyfsm/p/9673960.html CUDA(Compute Unified Device Architecture)的中文全称为计算统一设备架 ...
- 第二章 Matlab面向对象编程基础
DeepLab是一款基于Matlab面向对象编程的深度学习工具箱,所以了解Matlab面向对象编程的特点是必要的.笔者在做Matlab面向对象编程的时候发现无论是互联网上还是书店里卖的各式Matlab ...
- [.net 面向对象编程基础] (1) 开篇
[.net 面向对象编程基础] (1)开篇 使用.net进行面向对象编程也有好长一段时间了,整天都忙于赶项目,完成项目任务之中.最近偶有闲暇,看了项目组中的同学写的代码,感慨颇深.感觉除了定义个类,就 ...
- Android开发4: Notification编程基础、Broadcast的使用及其静态注册、动态注册方式
前言 啦啦啦~(博主每次开篇都要卖个萌,大家是不是都厌倦了呢~) 本篇博文希望帮助大家掌握 Broadcast 编程基础,实现动态注册 Broadcast 和静态注册 Broadcast 的方式以及学 ...
- T-Sql编程基础
T-sql编程 入门小游戏 T-sql编程基础,包括声明变量,if判断,while循环,以及使用一些基本函数. 记得在学校的时候,写过一个二人对打的文字输出游戏. 上代码 alter proc usp ...
随机推荐
- oracle数据表创建分区与查询
场景: 遇到1亿数据量的数据需要根据用户名做些数据统计分析,想直接做些聚合计算基本没可能,于是打算先根据日期按照年月创建分区,然后对各个分区分别进行统计,最后汇总结果. 有两种方法,分别是手工设置分区 ...
- node.js安装cnpm 提高下载速度
由于中国网络特殊的网络环境原因,国外部分网站访问速度很慢. 安装node.js时,使用npm 安装软件速度也很慢,可以使用阿里的cnpm来解决 官方网址:http://npm.taobao.org: ...
- Codeforce 287 div2 C题
题目链接:http://codeforces.com/contest/507/problem/C 解题报告:现在有一个满二叉树型的迷宫,入口在根结点,出口在第n个叶节点,有一串命令,LRLRLRLRL ...
- python 数据结构 初学时没太注意却发现很有用的点点滴滴
1. list.extend(L) 将指定列表中的所有元素附加到另一个列表的末尾:相当于a[len(a):] = L. 2. list.pop([i]) 删除列表中指定位置的元素并返回它.如果未指定索 ...
- event相关
event.button 事件属性可返回一个整数,指示当事件被触发时哪个鼠标按键被点击. event.keyCode 事件属性可返回一个整数,指示当事件被触发时哪个键盘按键被点击. <scri ...
- 一起入门python4之字典
今天我们来讲一下python的字典(dict).因为中午只有一个小时更新.所以更新内容不多,望多多指教,管他有没有人看,这都是对我的一种历练 .嘻嘻.其实我知道大多数论坛的牛牛都会.嘻嘻.I know ...
- OpenCV成长之路(7):图像滤波
滤波实际上是信号处理里的一个概念,而图像本身也可以看成是一个二维的信号.其中像素点灰度值的高低代表信号的强弱. 高频:图像中灰度变化剧烈的点. 低频:图像中平坦的,灰度变化不大的点. 根据图像的高频与 ...
- 使用Gitosis搭建Git服务器
使用Gitosis搭建Git服务器 作者: JeremyWei | 可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明 网址: http://weizhifeng.net/build- ...
- [k]css盒模型
box-sizing : content-box || border-box || inherit 1.content-box:此值为其默认值.元素的宽度/高度(width/height)等于元素边 ...
- .NET中六个重要的概念:栈、堆、值类型、引用类型、装箱和拆箱 (转)
作者: Edison Chou 来源: 博客园 发布时间: 2014-09-03 15:59 阅读: 318 次 推荐: 2 原文链接 [收藏] 原文作者:Shivprasad k ...