Section 0 :Induction of CUDA

CUDA是啥?CUDA®: A General-Purpose Parallel Computing Platform and Programming Model

为什么用显卡就可以实现比CPU高得多的运算性能呢?这要从GPU的结构讲起:

GPU天生是为了图像处理而设计的,讲道理的话它能处理一些简单的运算工作(比如单独的顶点和线段)。但是在一个GPU中包含了许多个流处理器(Stream Processor),这些流处理器都可以并行工作。In this sense, GPUs are stream processors – processors that can operate in parallel by running one kernel on many records in a stream at once. [Reference]

对于CPU来说,12核已经是上天了的配置。然而今天,随意一个亮机卡GPU都有96个CUDA计算单元(每个相当于一个计算核心)。其并行计算能力不可同日而语。

Section 1 :Thread Hierarchy

在CUDA的计算模型中,有如下几个concept:

1.thread

  这里的线程和CPU中其实是一个意思。是执行运算的最小单位。

  在执行时,每个线程都有一个自己独特的标识符 threadIdx。threadIdx可以是一维/二维/三维的。(threadIdx.x,threadIdx.y,threadIdx.z)

2.block (thread block)

  一个线程块包含了多个线程

3.Streaming Multiprocessor

  每个SM相当于一个计算单元,里面又包含很多个Streaming Processor。每个SM可并行运行一个block里的线程。

4.Kernel

  kernel可以理解成一个函数。同一个kernel函数可以在多个线程中被执行。

  比如下面的向量加法的程序:

 // Kernel definition
__global__ void VecAdd(float* A, float* B, float* C)
{
int i = threadIdx.x;
C[i] = A[i] + B[i];
}
int main()
{
...
// Kernel invocation with N threads
VecAdd<<<, N>>>(A, B, C);
...
}

  line 2:用__global__关键字定义了一个kernel函数

  line 4:threadIdx表示当前执行该kernel函数的这个thread的一个标号(可以理解为this指针的用途)

  line 11:在调用kernel函数时,需要分配<<number_of_blocks , threads_per_block>> 。上述程序中分配了一个block,每个block中N个thread

  虽然多个线程调用的都是同一个kernel function,但是它们分别在不同的数据空间进行加法运算(注意A、B、C的数组下标)。因此将一个大向量的加法运算给分解开了。

5.Grid

  不同种类的kernel,每kernel可以调度若干个block。这些block逻辑上被判为一个Grid。

thread、block和Streaming Multiprocessors的关系如下:

[Source: CUDA C Programming Guide.pdf]

如图,每个SM可以处理一个block,从而实现了并行计算。

两个层次的并行: • grid内多个block的并行 • block内多个thread的并行

注意:block和thread都是逻辑上的概念,物理上只存在SM。并不是一个SM一定严格对应一个block

比如对于我的亮机卡

每个SM可以跑1536个线程,而每个block最多1024个

但是实际上因为寄存器大小不一定够,并不一定能全部跑满这些线程。如果强行跑,就可能会爆掉

Section 2:Memory Hierarchy

[注意这里说的Memory都是指显存。CPU无法直接访问显存中的数据。][Reference]

因此,一个CUDA程序必然少不了以下三步:

☻cudaMalloc:创建新的动态显存堆

☻cudaMemcpy:将主机(Host)内存复制到设备(Device)显存

☻显存处理完之后,cudaMemcpy:设备(Device)显存复制回主机(Host)内存,释放显存cudaFree

CPU/RAM与GPU/VRAM的关系如图:[Reference]

Gird、block、thread的内存访问/共享机制如下图:

这里有几个概念:

  Local Memory:单个线程内使用的内存空间

  Shared Memory:一个block内所有线程共享的内存空间,常用于线程之间的通信。

             每个SM(StreamingMultiprocessor)大约有16KB的shared memory

  Global Memory:所有的block共享的内存空间。比shared速度慢,但是大许多

  Constant Memory:存储常量。一块显卡大约有64KB的constant memory

从硬件的角度来看结构是这样的:[Reference] [Reference]

                                 

最新文章

  1. 【学】React的学习之旅1
  2. iOS学习22之视图控制器
  3. CI实践_Android持续集成
  4. javascript实现KMP算法(没啥实用价值,只供学习)
  5. iOS打开手机QQ与指定用户聊天界面
  6. 13年山东省赛 Boring Counting(离线树状数组or主席树+二分or划分树+二分)
  7. Svn服务启动的两种方式
  8. 解题报告 HDU1176 免费馅饼
  9. jQuery获取Select选中的Text和Value,根据Value值动态添加属性等
  10. 关于sqlmap使用手册
  11. Sql Server 镜像相关
  12. B2B、B2C、B2D的简单理解
  13. 70.纯 CSS 创作一只徘徊的果冻怪兽
  14. java执行post请求,并获取json结果组成想要的内容存放本地txt中
  15. using强制对象清理资源 【转】
  16. Linux swap 使用
  17. 大话+图说:Java字节码指令——只为让你懂
  18. MySql(十七):MySql架构设计——高可用设计之思路及方案
  19. 解决spring中不同配置文件中存在name或者id相同的bean可能引起的问题
  20. {Repeater控件} Repeater控件的用法流程及实例

热门文章

  1. css3+jquery制作3d旋转相册
  2. ArcGIS Engine开发之空间查询
  3. Android MVP模式 谷歌官方代码解读
  4. 阶段一:用Handler和Message实现计时效果及其中一些疑问
  5. java socket传送一个结构体给用C++编写的服务器解析的问题
  6. Android开发案例 - 欢迎界面
  7. MVC下压缩输入的HTML内容
  8. ORACLE推导参数Derived Parameter介绍
  9. (六)Spark-Eclipse开发环境WordCount-Java&amp;Python版Spark
  10. APUE学习之多线程编程(一):线程的创建和销毁