一、传统的提高计算速度的方法

  • faster clocks (设置更快的时钟)
  • more work over per clock cycle(每个时钟周期做更多的工作)
  • more processors(更多处理器)

二、CPU & GPU

  • CPU更加侧重执行时间,做到延时小
  • GPU则侧重吞吐量,能够执行大量的计算

更形象的理解就是假如我们载一群人去北京,CPU就像那种敞篷跑车一样速度贼快,但是一次只能坐两个人,而GPU就像是大巴车一样,虽然可能速度不如跑车,但是一次能载超多人。

总结起来相比于CPU,GPU有如下特点:

  • 有很多计算单元,可以在一起执行大量的计算
  • 显示并行计算模型(explicitly parallel programming model),这个会在后面深度讨论
  • GPU是对吞吐量进行优化,而不是吞吐量

三、cuda登场

以前我们所写的代码都只能运行在CPU上,那么如果想运行在GPU上该怎么实现呢?

这时候就需要CUDA大大登场了!!!

cuda执行原理是CPU运行主程序,向GPU发送指示告诉它该做什么,那么系统就需要做如下的事情:

  • 1.把CPU内存中的数据转移到GPU的内存中
  • 2.将数据从GPU移回CPU

    (把数据从一个地方移到另一个地方命令为cudaMemcpy)
  • 3.在GPU上分配内存,在C语言中该命令是malloc,而在cuda中则是cudaMalloc
  • 4.在GPU上调用以并行方式计算的程序,这些程序叫做内核。

练习题:GPU可以做如下哪些事?



正确选项解释:

  • 选项2:回应CPU发来的请求,即对应上面的步骤2——将数据从GPU移回CPU
  • 选项4:回应CPU发来的请求,即对应上面的步骤1——把CPU内存中的数据转移到GPU的内存中
  • 选项5:计算由CPU调用的内核运算。

四、A CUDA Program

典型的GPU算法流程:

  • CPU在GPU上分配存储空间(cudaMalloc)
  • CPU将输入数据拷贝到GPU(cudaMemcpy)
  • CPU调用某些内核来监视这些在GPU上处理这个数据的内核(kernel launch)
  • CPU将GPU计算得到的结果复制回CPU(cudaMemcpy)

五、定义GPU计算

GPU能做的事是:

  • 有效的启动大量线程
  • 并行的运行上面启动的大量线程,而不是运行一个有很多并行工作的线程,也不是运行一个线程更加快速。

六、CPU&GPU计算原理区别

下面将计算数组[0,1,2……,63]每个元素平方来比较CPU和GPU计算原理的区别,以及具体代码实现。

CPU

for(i=0;i<64;i++){
out[i] = in[i] * in[i];
}

该段代码在CPU中执行,只有一个线程,它会循环64次,每次迭代做一个计算。

GPU

实现代码:

#include <stdio.h>

__global__ void cube(float * d_out, float * d_in){
// Todo: Fill in this function
int idx = threadIdx.x;
d_out[idx] = d_in[idx]+6;
} int main(int argc, char ** argv) {
const int ARRAY_SIZE = 64;
const int ARRAY_BYTES = ARRAY_SIZE * sizeof(float); // generate the input array on the host
float h_in[ARRAY_SIZE];
for (int i = 0; i < ARRAY_SIZE; i++) {
h_in[i] = float(i);
}
float h_out[ARRAY_SIZE]; // declare GPU memory pointers
float * d_in;
float * d_out; // allocate GPU memory
cudaMalloc((void**) &d_in, ARRAY_BYTES);
cudaMalloc((void**) &d_out, ARRAY_BYTES); // transfer the array to the GPU
cudaMemcpy(d_in, h_in, ARRAY_BYTES, cudaMemcpyHostToDevice); // launch the kernel
cube<<<1, ARRAY_SIZE>>>(d_out, d_in); // copy back the result array to the CPU
cudaMemcpy(h_out, d_out, ARRAY_BYTES, cudaMemcpyDeviceToHost); // print out the resulting array
for (int i =0; i < ARRAY_SIZE; i++) {
printf("%f", h_out[i]);
printf(((i % 4) != 3) ? "\t" : "\n");
} cudaFree(d_in);
cudaFree(d_out); return 0;
}

代码拆解分析:

1.变量命名规则

在编写cuda代码时,需要遵守如下规则,这样可以避免犯不必要的错误。

CPU的变量以h_开头(host),而GPU的变量以d_开头(device)。

2.定义内核函数

__global__ void square(float *d_out, float *d_in){
int idx = threadIdx.x;
float f = d_in[idx];
d_out[idx] = f * f;
}

通过 global 定义的函数可以让cuda知道这是一个内核函数。

函数第一行作用是通过内置的线程索引threadIdx获得当前线程的索引。另外threadIdx是c语言中的struct,它有3名成员,分别是 .x,.y,.z 。如果该线程是第一个线程,则threadIdx.x返回的值是0

3.数据转移cudaMemcpy

代码片段

// 将数据转移到GPU
cudaMemcpy(d_in, h_in, ARRAY_BYTES, cudaMemcpyHostToDevice); // 调用内核
square<<<1, ARRAY_SIZE>>>(d_out, d_in); // 将结果传回CPU
cudaMemcpy(h_out, d_out, ARRAY_BYTES, cudaMemcpyDeviceToHost);

注意下面函数的第三个参数direction有三种选项:

cudaMemcpy(destination, source, size, direction)

分别是:

  • cudaMemcpyHostToDevice
  • cudaMemcpyDeviceToHost
  • cudaMemcpyDeviceToDevice

4.调用内核 square<<<1, 64>>>

另外在解释一下如上函数各参数的含义:

第一个参数1表示需要分配的的数量为1,

第二个参数64表示每一块有64个线程。

所以假设我们需要1280个线程,我们就可以这样定义:

square<<<10,128>>>(param1, param2);

或者

square<<<5,256>>>(param1, param2);

BUT!!! 要注意不能像下面这样定义,因为一个块的线程数一般没那么大,一般只有1024.

square<<<1,1280>>>(param1, param2);

还需要知道的是上面介绍的两个参数其实可以是二维或者三维的,即

square<<<1,64>>> 等效为 square<<<dim3(1,1,1),dim3(64,1,1)>>> ,但是dim3(64,1,1)=dim3(64)=64。

例如我们有一个128*128的图片,现在需要对每一个像素进行计算,我们可以是

<<<dim3(128,1,1),(128,1,1)>>>,也可以是<<<dim3(8,8,1),dim3(16,16,1)>>>

总结起来核函数的调用的完整形式是

kernel<<<dim3(bx,by,bz), dim3(tx,ty,tz), shmem>>>(...)

第一个参数表示网络块的维数(bx * by * bz),

第二个参数表示每块所含有的线程数(tx * ty * tz)

第三个参数一般默认为0,它是以字节表示的每个线程块分配的共享内存量

![]https://ask.qcloudimg.com/http-save/yehe-1215004/q3rf2iq5r.png?imageView2/2/w/1620)

【Udacity并行计算课程笔记】- lesson 1 The GPU Programming Model的更多相关文章

  1. 【Udacity并行计算课程笔记】- Lesson 2 The GPU Hardware and Parallel Communication Patterns

    本小节笔记大纲: 1.Communication patterns gather,scatter,stencil,transpose 2.GPU hardware & Programming ...

  2. Udacity并行计算课程笔记-The GPU Hardware and Parallel Communication Patterns

    本小节笔记大纲: 1.Communication patterns gather,scatter,stencil,transpose 2.GPU hardware & Programming ...

  3. Udacity并行计算课程笔记-The GPU Programming Model

    一.传统的提高计算速度的方法 faster clocks (设置更快的时钟) more work over per clock cycle(每个时钟周期做更多的工作) more processors( ...

  4. 【Udacity并行计算课程笔记】- Lesson 4 Fundamental GPU Algorithms (Applications of Sort and Scan)

    I. Scan应用--Compact 在介绍这节之前,首先给定一个情景方便理解,就是因为某种原因我们需要从扑克牌中选出方块的牌. 更formal一点的说法如下,输入是 \(s_0,s_1,...\), ...

  5. 【Udacity并行计算课程笔记】- Lesson 3 Fundamental GPU Algorithms (Reduce, Scan, Histogram)

    本周主要内容如下: 如何分析GPU算法的速度和效率 ​​3个新的基本算法:归约.扫描和直方图(Reduce.Scan.Histogram) 一.评估标准 首先介绍用于评估GPU计算的两个标准: ste ...

  6. udacity android 学习笔记: lesson 4 part b

    udacity android 学习笔记: lesson 4 part b 作者:干货店打杂的 /titer1 /Archimedes 出处:https://code.csdn.net/titer1 ...

  7. udacity android 实践笔记: lesson 4 part b

    udacity android 实践笔记: lesson 4 part b 作者:干货店打杂的 /titer1 /Archimedes 出处:https://code.csdn.net/titer1 ...

  8. udacity android 学习笔记: lesson 4 part a

    udacity android 学习笔记: lesson 4 part a 作者:干货店打杂的 /titer1 /Archimedes 出处:https://code.csdn.net/titer1 ...

  9. udacity android 实践笔记: lesson 4 part a

    udacity android 实践笔记: lesson 4 part a 作者:干货店打杂的 /titer1 /Archimedes 出处:https://code.csdn.net/titer1 ...

随机推荐

  1. tomcat运行JSP时产生的错误:”javax.servlet.servletexception: java.lang.nosuchmethoderror”

    这个错误其实是多次重复编译JAVA文件导致的,需要clean操作,简单的来说就是删除tomcat下work文件夹中工作空间,也可以理解为自己的虚拟路径,比如我运行的jsp的路径:localhost:8 ...

  2. kafka学习总结之kafka简介

    kafka是一个分布式,基于subscribe-publish的消息系统 特性:高吞吐量.低延迟.可扩展性.持久性(消息持久化到本地磁盘).可靠性.容错性(n个副本,允许n-1个节点失败).高并发(支 ...

  3. 软工实践练习一 git使用心得

    使用git进行代码管理的心得 小组 1.结对的同学创建了小组,我属于被邀请的.附上图片一张. 2.已将代码库https://github.com/sefzu2015/AutoCS fork到了小组or ...

  4. 团队作业之旅游行业APP分析

    随着经济的发展,不论是在工作中的男女老少,还是在校园中的童鞋,都喜欢在假期来一场说走就走的旅行,来缓解生活中的各种压力.当然,在国家面临经济转型的情况下,更多的将工业,农业转向服务型的旅游业,各个省市 ...

  5. ElasticSearch 2 (32) - 信息聚合系列之范围限定

    ElasticSearch 2 (32) - 信息聚合系列之范围限定 摘要 到目前为止我们看到的所有聚合的例子都省略了搜索请求,完整的请求就是聚合本身. 聚合与搜索请求同时执行,但是我们需要理解一个新 ...

  6. UML时序图学习

    定义 时序图主要用于展示对象之间交互的顺序. 时序图将交互关系表示为一个二维图.纵向是时间轴,时间沿竖线向下延伸.横向轴代表了在协作中各独立对象的类元角色.类元角色用生命线表示.当对象存在时,角色用一 ...

  7. codeforces1A

    Theatre Square CodeForces - 1A 一个城市的广场面积有 N×M平方米,过段时间,恰逢这个城市的庆典活动,主办方决定在广场上铺设一种新的地砖,这种地砖每块都是a×a平方米的. ...

  8. Pycharm+Python+PyQt5使用

    https://www.cnblogs.com/dalanjing/p/6978373.html

  9. 如何整合Office Web Apps至自己开发的系统(一)

    在前面我的一篇博客中 Office Web Apps安装部署(一),有一张介绍Office Web Apps与其他系统的关系图,   从上述图中,可知实际上Office Web Apps也是可以接入自 ...

  10. 【转】单片机系统中数字滤波的算法【C程序整理】

    随机误差是有随机干搅引起的,其特点是在相同条件下测量同一个量时,其大小和符号做无规则变化而无法预测,但多次测量结果符合统计规律.为克服随机干搅引入的误差,硬件上可采用滤波技术,软件上可以采用软件算法实 ...