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 ...
随机推荐
- Tomcat的安装与配置
Windows安装Tomcat与启动 安装版安装 安装版长这个样子,下载到电脑上后双击开始安装 双击后出现如下页面,点击 Next> 之后是这个页面,点击 I Agree 之后出现如下页面,点击 ...
- Async分析
1:android在新版本中不允许UI线程访问网络,但是如果需要访问网络又改怎么办呐?这里有很多解决方案,比如新开一个线程,在新线程中进行访问,然后访问数据,返回后可能会更新界面也可能不更新界面,这 ...
- ubuntu安装fat32和exfat文件系统支持
vftp(fat32) apt install -y dosfstools exfat apt install -y exfat-fuse exfat-utils
- HTTP与TCP的关系
一直比较想写TCP与HTTP之间的关系,HTTP报文是如何通过tcp发送的,HTTP报文形式内容如何. HTTP请求包含请求行,请求头,请求体 HTTP响应包含响应头,响应头,响应体 下面我准备通过J ...
- 南京邮电大学java程序设计作业在线编程第五次作业
王利国的"Java语言程序设计第5次作业(2018)"详细 主页 我的作业列表 作业结果详细 总分:100 选择题得分:50 1. 以下哪一个工具是Java的编译器?( ) A. ...
- JAVA中抽象类的使用
抽象类是从多个具体类中抽象出来的父类,它具有更高层次的抽象.抽象类体现的就是一种模板模式的设计,抽象父类可以只定义需要使用的某些方法,把不能实现的某些部分抽象成抽象方法,留给其子类去实现.具体来说,抽 ...
- ELK学习记录一 :初识ELK
ELK是elastic公司提供的一套完整的收集日志并分析展示的产品,分别表示Elasticsearch.Logstash和kibana. (官网截个图) 先来一段个人粗浅的认识: Elasticsea ...
- Dynamics CRM2016 Web Api之分页查询
在dynamics crm web api还没出现前,我们是通过fetchxml来实现的,当然这种方式依旧可行,那既然web api来了我们就拥抱新的方式. web api中我们通过指定查询的条数来实 ...
- Bootstrap3 栅格系统-列排序
通过使用 .col-md-push-* 和 .col-md-pull-* 类就可以很容易的改变列(column)的顺序. <div class="row"> <d ...
- DB 查询分析器7.01 新增的保存执行结果到多个文件功能
1 引言 中国本土程序员马根峰(CSDN专访马根峰:海量数据处理与分析大师的中国本土程序员)推出的个人作品----万能数据库查询分析器,中文版本DB 查询分析器.英文版本< ...