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. UE32修改TAB键为空格键

  2. jQuery基础学习(二)—jQuery选择器

    一.jQuery基本选择器 1.CSS选择器     在学习jQuery选择器之前,先介绍一下之前学过的CSS选择器. 选择器 语法 描述 示例   标签选择器 E {                 ...

  3. nginx反向代理的nginx.conf配置

    下面的配置是nginx.conf的示例 nginx反向代理 就是说把跨域的url通过本地代理的方式,变成同域的请求,如此来解决跨域问题 该配置下 通过http://localhost/html5/路径 ...

  4. SqlDataReader生成动态Lambda表达式

    上一扁使用动态lambda表达式来将DataTable转换成实体,比直接用反射快了不少.主要是首行转换的时候动态生成了委托. 后面的转换都是直接调用委托,省去了多次用反射带来的性能损失. 今天在对Sq ...

  5. node.js 中模块的循环调用问题详解

    首先,我们看一下图示代码,每一个注释其实代表一个 js 文件.所以下面其实是三个 js 文件 .第一个是我们要运行的 main 文件,后面两个是 a, b 文件.   从上面可以看书 a ,b 两个模 ...

  6. 让你的JS代码更具可读性

    一.合理的添加注释 函数和方法--每个函数或方法都应该包含一个注释,描述其目的和用于完成任务所可能使用 的算法.陈述事先的假设也非常重要,如参数代表什么,函数是否有返回值(因为这不能从函 数定义中推断 ...

  7. c# 基础算法(一) 九九乘法

    闲来无事,偶见某贴子里面讨论面试题.突然对一题产生了兴趣,做一道99乘法打印(主要是我工作了2家单位,还没有一家单位在面试时给我出这一道题)于是试着自己写写看.大概逻辑如下 class program ...

  8. bzoj4800 [Ceoi2015]Ice Hockey World Championship

    Description 有n个物品,m块钱,给定每个物品的价格,求买物品的方案数. Input 第一行两个数n,m代表物品数量及钱数 第二行n个数,代表每个物品的价格 n<=40,m<=1 ...

  9. stl_container容器和std_algorithm算法相同的函数

    八.算法和容器中存在的功能相同的函数: 8.1.array: 8.1.1.fill. 1.在array中:void fill (const value_type& val); 2.在algor ...

  10. 【WPF】学习笔记(二)——依旧是一个电子签名板

    这篇博客呢,主要谈谈在实现电子签名功能中踩过的几个坑:1.System.BadImageFormatException异常:2.无法加载DLL“###.dll”,: 找不到指定的模块. (异常来自 H ...