CUDA学习,第一个kernel函数及代码讲解
前一篇CUDA学习,我们已经完成了编程环境的配置,现在我们继续深入去了解CUDA编程。本博文分为三个部分,第一部分给出一个代码示例,第二部分对代码进行讲解,第三部分根据这个例子介绍如何部署和发起一个kernel函数。
二、代码解说
申明一个函数,用于检测CUDA运行中是否出错。
kernel函数,blockIdx.x表示block在x方向的索引号,blockDim.x表示block在x方向的维度,threadIdx.x表示thread在x方向的索引号。
这里也许你会问,为什么在x方向?难道还有其他方向?
对的,grid可以是一维、二维,block可以是一维、二维和三维的。一个grid里包含多个block,一个block里也包含多个thread,可参考下图。
从而,i是每个thread的索引号,也许你会问为什么不直接是threadIdx.x呢?
因为每个block里的threadIdx.x都是从0到blockDim.x(假设block是一维的),那么不同的block里threadIdx.x会出现相同的值,我们就不知道该调用那个thread来执行,因为用threadIdx.x+blockIdx.x*blockDim.x表示每个thread的索引号,这样就是唯一的了。举个例子,假设grid和block都是一维的,blockDim.x=8,threadIdx.x从0到7,blockIdx.x也是从0到7,那么i就是0,1,2,3,4,5,6,7,8,9,10,11...63,从而保证了每个thread索引号的唯一性。
申请两个指针*h_a和*d_a,分别指向host内存和device内存,host是指主程序cpu内存,device是指gpu内存(global
memory)。并定义一个grid里block数(即numBlocks)和每个block里thread数numThreadsPerBlock。
分配host和device内存,cudaMalloc((void**)&d_a,memSize)是给device中d_a分配memSize字节的内存,为什么前面有(void**)&呢?因为这个内存分配要通过cpu传给gpu。
部署并发起kernel函数,,1),一维的grid,里面包含,1),grid里每个block都是一维的,每个block有numThreadsPerBlock个thread。发起kernel函数:myFirstKernel<<<dimGrid,dimBlock>>>(d_a),第一个是函数名,括号里是kernel的部署,后面一个是函数的参数。
同步并检查kernel函数运行是否出错。为什么要同步呢?因为每个thread运行的时间是不一样的,只有等所有线程都跑完了,我们才做下一件事。这会造成运行的性能降低,但是是必要的。
cudaMemcpy函数完成数据在host和device之间的传输,第一个参数是传输的目标,第二个参数是传输的源数据,第三个参数传输的数据量,第四个参数是传输的方向,这里是从device传到host。
检查cudaMemcpy函数运行是否出错。
检查从device传回的数据是否正确。
释放host和device内存。
检查CUDA函数是否运行正确的函数。
三、部署和发起一个kernel函数
如上述,对kernel函数先申明,在函数体中实现线程的算法,即:
然后部署和发起kernel函数,即:
综上,我们完成代码的讲解,部署和发起一个kernel函数。想必你现在应该对CUDA有了较为深入的了解了!是吧?
CUDA学习,第一个kernel函数及代码讲解的更多相关文章
- CUDA学习笔记1:第一个CUDA实例
一.cuda简介 CUDA是支持c++/c语言,一般我喜欢用c来写,他的编译是gpu部分由nvcc来进行的 一般的函数定义 void function(); cuda的函数定义 __global ...
- CUDA学习笔记4:CUDA(英伟达显卡统一计算架构)代码运行时间测试
CUDA内核运行时间的测量函数 cudaEvent_t start1; cudaEventCreate(&start1); cudaEvent_t stop1; cudaEventCreate ...
- 除了信号触发线程与接收者线程相同的情况能直接调用到slot,其它情况都依赖事件机制(解决上面代码收不到信号的问题其实很简单,在线程的run();函数中添加一个事件循环就可以了,即加入一句exec();),信号槽不就是一个回调函数嘛
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { pThreadCon = new CSerialThread ...
- Python学习笔记(五)函数和代码复用
函数能提高应用的模块性,和代码的重复利用率.在很多高级语言中,都可以使用函数实现多种功能.在之前的学习中,相信你已经知道Python提供了许多内建函数,比如print().同样,你也可以自己创建函数, ...
- python定义的一个简单的shell函数的代码
把写代码过程中经常用到的一些代码段做个记录,如下代码段是关于python定义的一个简单的shell函数的代码. pipe = subprocess.Popen(cmd, stdout=subproce ...
- jquery动画函数里面可以跟一个回调函数,表示动画结束后执行的代码
jquery动画函数里面可以跟一个回调函数,表示动画结束后执行的代码 使用js监听动画结束后进行的操作: $ele.fadeIn(300,function(){...}) $ele.fadeOut(3 ...
- CUDA学习笔记(二)【转】
来源:http://luofl1992.is-programmer.com/posts/38847.html 编程语言的特点是要实践,实践多了才有经验.很多东西书本上讲得不慎清楚,不妨自己用代码实现一 ...
- CUDA学习笔记1
最近要做三维重建就学习一下cuda的一些使用. CUDA并行变成的基本四路是把一个很大的任务划分成N个简单重复的操作,创建N个线程分别执行. CPU和GPU,有各自的存储空间: Host, CPU a ...
- CUDA学习笔记-1: CUDA编程概览
1.GPU编程模型及基本步骤 cuda程序的基本步骤如下: 在cpu中初始化数据 将输入transfer到GPU中 利用分配好的grid和block启动kernel函数 将计算结果transfer到C ...
随机推荐
- CentOS7.2安装mysql5.6
1.卸载系统自带的Mariadb [root@localhost~]# rpm -qa|grep mariadb //查询出已安装的mariadb [root@localhost~]# rpm -e ...
- 数据结构之Treap
1. 概述 同splay tree一样,treap也是一个平衡二叉树,不过Treap会记录一个额外的数据,即优先级.Treap在以关键码构成二叉搜索树的同时,还按优先级来满足堆的性质.因而,Treap ...
- env-cmd 从文件读取配置变量
npm install --registry=https://registry.npm.taobao.org -D env-cmd So.. 这样你在npm run build的时候会发现输出文件里面 ...
- GCT学习总结
GCT的一个综合的考试性质,时间紧,题量大,这个时候需要我们快速.准确的答题,把自己的能力展现在其中,十一期间和同学们一起学习.讨论,大家都提高很大,各科谈一下自己的心得 数学: 数学相对来说还是不难 ...
- [BBS]搭建开源论坛之JForum安装使用札记
本文作者:sushengmiyan 本文地址:http://blog.csdn.net/sushengmiyan/article/details/47761303 目录 目录 BBS搭建开源论坛之JF ...
- 自定义支持多行显示的RadioGroup
自定义支持多行显示的RadioGroup 原生的RadioGroup继承自LinearLayout,即只能支持一横排或者一竖排的排列显示RadioButton 现在改写RadioGroup,使它支持多 ...
- Android视频媒体相关,VideoView和开源框架vitamio
虽然Android已经内置了VideoView组件和MediaPlayer类来支持开发视频播放器,但支持格式.性能等各方面都十分有限,但是Vitamio的确强大到没朋友! Vitamio 是一款 An ...
- 如何获得Android手机的软件安装列表
Android的PackageManager类用于检索目前安装在设备上的应用软件包的信息.你可以通过调用getpackagemanager()得到PackageManager类的一个实例.对查询和操作 ...
- mysql进阶(二十八)MySQL GRANT REVOKE用法
mysql进阶(二十八)MySQL GRANT REVOKE用法 MySQL的权限系统围绕着两个概念: 认证->确定用户是否允许连接数据库服务器: 授权->确定用户是否拥有足够的权限执 ...
- Dynamics CRM2013 流程拷贝
在CRM中工作流是一个非常不错的功能,在实际业务场景中能满足各种业务需求.在我们设置一个工作流的时候,同一个实体一个逻辑功能可能需要多个工作流来实现,而多个工作流的不同之处可能只是启动时间或者是步骤中 ...