status
type
date
slug
summary
tags
category
icon
password
争取3个月的时间 对cuda基础操作熟悉
数据并行 首先需要给线程做分配
- 块划分 分多个数据小块 随机处理
- 周期划分 固定轮流每个线程执行数据块


计算机架构:
常见的是 单指令 → 多数据 多指令 → 多数据
关键词: 延迟(操作时间) 带宽(单位时间处理数据量) 吞吐量(单位时间成功运算数量)
内存视角来说:
分布式内存 → 机房 服务器集群 内存通过网络连接
单主板多处理器 → 共享用一片内存寻址空间
CPU和GPU线程的区别:
- CPU线程是重量级实体,操作系统交替执行线程,线程上下文切换花销很大
- GPU线程是轻量级的,GPU应用一般包含成千上万的线程,多数在排队状态,线程之间切换基本没有开销。
- CPU的核被设计用来尽可能减少一个或两个线程运行时间的延迟,而GPU核则是大量线程,最大幅度提高吞吐量
对于GPU resource API 调用有两种方式(不可以混合调用)
- CUDA Driver → CPU 中最底层 紧贴GPU
- CUDA Runtime → higher level API

一个CUDA应用通常可以分解为两部分,
- CPU 主机端代码
- GPU 设备端代码
CUDA nvcc编译器会自动分离你代码里面的不同部分,如图中主机代码用C写成,使用本地的C语言编译器编译,设备端代码,也就是核函数,用CUDA C编写,通过nvcc编译,链接阶段,在内核程序调用或者明显的GPU设备操作时,添加运行时库。
NVCC ← LLVM 编译器
CUDA toolkit 包含 nvcc? libraries, developer tools
我们先开始看hello world
什么叫做在Kernel上编程?
我们首先要了解Kernel是什么 Kernel其实是function that executed in parallel fashion by multiple threads
thread.index
grid → block: {thread1, thread2, } Threads in a block work together and share memory
sm负责执行 thread blocks 在这里 further organized into wraps
(32 threads execute instructions in a single cycle)
Each SM has cores, registers, shared memory (Core number varies)
multiple SMs can execute different thread blocks simultaneously(→ direct parallelism)
large number of thread blocks will be distributed automatically?
Launch Kernel → need to define #of block/thread to be created
each thread execute independently, and what data it operates is controlled by thread.index
我们来看一个基础hello world
一个更加直观的
几个关键词:
__global__ declare kernel function (run on GPU, called from CPU) 注意这里的从主机调用
__device__ 从设备端调用
Kernel核函数编写有以下限制
- 只能访问设备内存
- 必须有void返回类型
- 不支持可变数量的参数
- 不支持静态变量
- 显示异步行为
<<<#Block, #Threads>>> 用来specify Kernel function 还可以规定3D block size
接受dim3类型 grid/block维度 或int 这里是说每一个B对应的threads数
cudaDeviceSynchronize() → Blocks CPU thread until all threads on GPU finished 同步CPU/GPU
两个设备本身是异步的 也就是CPU线程调用完kernel func 就会继续这个program
不管执行情况
ensure all launched kernels and memory operations are completed before program proceeds
一般CUDA程序分成下面这些步骤:
- 分配GPU内存
- 拷贝内存到设备
- 调用CUDA内核函数来执行计算
- 把计算完成数据拷贝回主机端
- 内存销毁
CUDA抽象了硬件实现:
- 线程组的层次结构
- 内存的层次结构
- 障碍同步
我们看怎么把简单操作转换成并行
但是这样是否以为这我们需要 size n个的线程量
验证kernel func
以上使用了几个基础的内存管理 api
cudaMalloc
只有在malloc中需要 pointer 因为需要
cudaMemcpy
cudaMemset → Device memory 初始化
cudaFree
只能释放通过
cudaMalloc/cudaMallocManaged
分配的内存释放后应将指针设为
NULL
防止野指针参考:
- Author:ran2323
- URL:https://www.blueif.me//article/19371a79-6e22-802f-9226-d91773dde817
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!