cuda作为gpu计算中的代表,拥有着超级高的计算效率,其原因是gpu实际相当与一台超级并行机组,使用过MPI做并行计算的人们可能知道,所谓的并行计算,简单讲就是用多个U(计算单元)来完成一个U的计算任务,MPI中将其叫做核,我们知道一个cpu有一个或2,4,8个核,超级厉害的也就16个吧,原来人们为了做大规模的并行计算,将一大堆cpu装在柜子里,组成计算集群,但是那种设备大的吓人,而且又有多少人会用呢。gpu则不同,一个小小的芯片上就存在着成千上万的线程,是由分为grid,block,thread三级结构实现的。(本人初学者,学到哪写到哪,借鉴需谨慎)

  所谓的并行计算,就是用多个计算单元共同完成一个计算任务,那这有什么难度呢,这在生活中很常见啊,似乎没什么可学的,可以想象我们造一座房子,我们要找一堆人过来,然后分配下任务,这里面有人做墙,有人做地板,屋顶等等吧,然后一声令下开始吧,大家各司其职,把自己那部分做好,房子就做好了。但是事情没有那么简单,这个过程中存在很多问题会影响效率,甚至结果。比如说做墙的人要用锤子,但是锤子在被其他人占用着,怎么办;做地板的把地做好了,但是又被做墙的人给不小心砸坏了;下面的结构还没做好,就有人来装屋顶了等等。这时就需要一个精确的管理方案,而这个管理方案就是所有并行API需要做的事。例如后面会学到的共享内存,同步等知识。目前看到书就是cuda by example了,很适合入门,看的很愉快。下面就开始了,什么hello world就不写了,直接学干货了。

 /*
* Copyright 1993-2010 NVIDIA Corporation. All rights reserved.
*
* NVIDIA Corporation and its licensors retain all intellectual property and
* proprietary rights in and to this software and related documentation.
* Any use, reproduction, disclosure, or distribution of this software
* and related documentation without an express license agreement from
* NVIDIA Corporation is strictly prohibited.
*
* Please refer to the applicable NVIDIA end user license agreement (EULA)
* associated with this source code for terms and conditions that govern
* your use of this NVIDIA software.
*
*/ #include "../common/book.h" #define N 10 __global__ void add( int *a, int *b, int *c ) {
int tid = blockIdx.x; // this thread handles the data at its thread id
if (tid < N)
c[tid] = a[tid] + b[tid];
} int main( void ) {
int a[N], b[N], c[N];
int *dev_a, *dev_b, *dev_c; // allocate the memory on the GPU
HANDLE_ERROR( cudaMalloc( (void**)&dev_a, N * sizeof(int) ) );
HANDLE_ERROR( cudaMalloc( (void**)&dev_b, N * sizeof(int) ) );
HANDLE_ERROR( cudaMalloc( (void**)&dev_c, N * sizeof(int) ) ); // fill the arrays 'a' and 'b' on the CPU
for (int i=; i<N; i++) {
a[i] = -i;
b[i] = i * i;
} // copy the arrays 'a' and 'b' to the GPU
HANDLE_ERROR( cudaMemcpy( dev_a, a, N * sizeof(int),
cudaMemcpyHostToDevice ) );
HANDLE_ERROR( cudaMemcpy( dev_b, b, N * sizeof(int),
cudaMemcpyHostToDevice ) ); add<<<N,>>>( dev_a, dev_b, dev_c ); // copy the array 'c' back from the GPU to the CPU
HANDLE_ERROR( cudaMemcpy( c, dev_c, N * sizeof(int),
cudaMemcpyDeviceToHost ) ); // display the results
for (int i=; i<N; i++) {
printf( "%d + %d = %d\n", a[i], b[i], c[i] );
} // free the memory allocated on the GPU
HANDLE_ERROR( cudaFree( dev_a ) );
HANDLE_ERROR( cudaFree( dev_b ) );
HANDLE_ERROR( cudaFree( dev_c ) ); return ;
}

这段代码讲述了如何将两个长度是10的向量相加,属于gpu计算中基础中的基础,我们借助这段毫无难度的代码熟悉一下cuda中的一些基本规则。

首先,每一个cuda代码中必有kernel函数,也就是前面标有__global__的函数,如下:

 __global__ void add( int *a, int *b, int *c ) {
int tid = blockIdx.x; // this thread handles the data at its thread id
if (tid < N)
c[tid] = a[tid] + b[tid];
}

kernel函数的用意就是gpu中的每一个thread都会执行kernel,从而达到并行的目的。a,b,c三个参数传入所有thread,每一个thread完成加法操作,为了使每一个thread的加法是对应数组中不同的元素,所以变量tid就意义重大,blockIdx.x是runtime中提供的变量,通常来讲,一个gpu有1个grid,1个grid有多个block,这些block以一维或二维或三维数组的形式排列,blockIdx.x就是每个block在x方向上的索引值(就是序号),而每一个block又可以分为多个thread,thread按照一维或二维的方式排列。网上摘图一个,以供理解

这个图还说明了一个kernel就有一个grid,多个kernel有多个grid,涨姿势。

接着说 tid = blockIdx.x,就是说要把每一个block的序号赋值给tid,block的序号是0,1,2,。。。这样排列的,数组a,b,c的索引值tid也是0,1,2.。。。这样的,这不就说明每个block都会计算他自己的那个数组分量了,这不是巧了吗。

cudaMalloc( (void**)&dev_a, N * sizeof(int) )函数可以在device上申请存储空间,这里有一个原则,就是host中的代码不能操作用cudaMalloc申请的空间,因此想要释放空间,用cudaFree。kernel才是操作cudaMalloc申请的变量的函数,kernel中用到的其他函数需要以__device__标明。

为变量申请空间后用函数cudaMemcpy( dev_a, a, N * sizeof(int), cudaMemcpyHostToDevice )把host中的变量a赋值进device中即dev_a。然后device自己计算自己那份任务,即kernel中的计算。计算后用函数cudaMemcpy( c, dev_c, N * sizeof(int), cudaMemcpyDeviceToHost )将结果dev_c传会host。整体就是这么个流程。

  需要注意的是对计算发出命令的add<<<N,1>>>( dev_a, dev_b, dev_c );kernel函数在调用时需要两个参数,参数告诉runtime如何launch the kernel,就是怎么把kernel复制给那些计算单元的意思吧N代表N个一维block,1代表每个block里面包含1个thread。

cuda学习1-初始庐山真面目的更多相关文章

  1. CUDA学习,第一个kernel函数及代码讲解

    前一篇CUDA学习,我们已经完成了编程环境的配置,现在我们继续深入去了解CUDA编程.本博文分为三个部分,第一部分给出一个代码示例,第二部分对代码进行讲解,第三部分根据这个例子介绍如何部署和发起一个k ...

  2. [Android进阶]Binder学习(初始篇)

    Android中Binder学习(初始篇) 本篇博客学习自侯亮的博客.地址为: 红茶一杯话Binder 1 什么是Binder? 简单地说.Binder是Android平台上的一种跨进程交互技术. 该 ...

  3. CUDA学习之二:shared_memory使用,矩阵相乘

    CUDA中使用shared_memory可以加速运算,在矩阵乘法中是一个体现. 矩阵C = A * B,正常运算时我们运用 C[i,j] = A[i,:] * B[:,j] 可以计算出结果.但是在CP ...

  4. CUDA学习之一:二维矩阵加法

    今天忙活了3个小时,竟然被一个苦恼的CUDA小例程给困住了,本来是参照Rachal zhang大神的CUDA学习笔记来一个模仿,结果却自己给自己糊里糊涂,最后还是弄明白了一些. RZ大神对CUDA关于 ...

  5. cuda学习2-block与thread数量的选取

    由上一节可知,在main函数中,cuda程序的并行能力是在add<<<N,1>>>( dev_a, dev_b, dev_c )函数中体现的,这里面设置的是由N个b ...

  6. CUDA学习笔记(三)——CUDA内存

    转自:http://blog.sina.com.cn/s/blog_48b9e1f90100fm5f.html 结合lec07_intro_cuda.pptx学习 内存类型 CGMA: Compute ...

  7. CUDA学习笔记(二)【转】

    来源:http://luofl1992.is-programmer.com/posts/38847.html 编程语言的特点是要实践,实践多了才有经验.很多东西书本上讲得不慎清楚,不妨自己用代码实现一 ...

  8. CUDA学习ing..

    0.引言 本文记载了CUDA的学习过程~刚开始接触GPU相关的东西,包括图形.计算.并行处理模式等,先从概念性的东西入手,然后结合实践开始学习.CUDA感觉没有一种权威性的书籍,开发工具变动也比较快, ...

  9. cuda学习3-共享内存和同步

    为什么要使用共享内存呢,因为共享内存的访问速度快.这是首先要明确的,下面详细研究. cuda程序中的内存使用分为主机内存(host memory) 和 设备内存(device memory),我们在这 ...

随机推荐

  1. Java 9 尝鲜之JShell交互式编程环境

    JShell--Java 9 的交互式编程环境 本文要求读者有基本的 Java 知识. Tips Java 9 的代码由于提供了新特性,所以有些代码并不支持向后兼容.也就是说,用 Java 9 写的代 ...

  2. 每天一个linux命令(63):Linux中zip压缩和unzip解压缩命令详解

    文章转自:http://www.jb51.net/LINUXjishu/105916.html 1.把/home目录下面的mydata目录压缩为mydata.zipzip -r mydata.zip ...

  3. python在cmd上导包成功,但是python charm上面就提示找不到

    失败 成功 原因:我的python file名称和numpy 的名字一样了,把python file 的名字改了就好了

  4. 关于Java中String类的hashCode方法

    首先来看一下String中hashCode方法的实现源码 public int hashCode() { int h = hash; if (h == 0 && value.lengt ...

  5. 三、Dotnet Core Code First 创建数据库

    1.在项目中创建Models文件夹2.在Models文件夹中建立 表的属性类:如 User类.3.在Models文件夹创建DataContext 继承DbContext类(可以选择重写OnModelC ...

  6. Block Token 原理分析

    介绍 文件权限检查由NameNode执行,而不是DataNode执行. 默认情况下,任何客户端都可以访问只有其块ID的任何块. 为了解决这个问题,Hadoop引入了块访问令牌的概念. 块访问令牌由Na ...

  7. poj1159二维树状数组

    Suppose that the fourth generation mobile phone base stations in the Tampere area operate as follows ...

  8. TP5学习基础一:增删改查小demo

    ①TP5--增删改查简单的demo 我先吐槽一下:因为工作需要研究tp5,去官网看了一下哎呦,资源挺多挺全啊!然后下载唯一免费的官方教程,我曹pdf打开533页.讲的很细但是开发能等看完才做吗?看到精 ...

  9. O(mn)实现LCIS

    序: LCIS即求两序列的最长公共不下降子序列.思路于LCS基本一致. 用dp[i][j]记录当前最大值. 代码实现: /* About: LCIS O(mn) Auther: kongse_qi D ...

  10. 工具类总结---(六)---之http及https请求

    下面使用的是HttpURLConnection进行的网络链接,并对https进行了忽略证书. 在这个utils里面,也使用到前面几个utils,比如下载文件的方法,就使用到了Fileutils pac ...