CUDA 入门到实战:GPU 并行计算学习全攻略
·
一、CUDA 是什么?为什么要学 CUDA?
1.1 基本定义
CUDA(Compute Unified Device Architecture)是 NVIDIA 推出的通用并行计算平台与编程模型,允许开发者使用类 C/C++ 语言调用 NVIDIA GPU 的并行计算核心,执行大规模并行任务。
1.2 核心优势
- 超强并行能力:单 GPU 包含上千个计算核心,适合数据并行、计算密集型任务
- 开发友好:基于 C/C++ 扩展,学习成本低,支持 C++17 等现代语法
- 生态完善:深度适配 PyTorch/TensorFlow、cuDNN、NCCL、OpenCV 等库
- 应用广泛:AI 训练 / 推理、视频编解码、流体仿真、图像处理、量化交易
1.3 适用场景
- 深度学习模型训练与推理加速
- 图像滤波、目标检测、特征提取
- 矩阵运算、FFT、数值求解
- 大规模数据批处理、科学仿真
二、CUDA 开发环境搭建
2.1 环境要求
- 硬件:NVIDIA 显卡(算力 ≥ 3.5,推荐 ≥ 7.0)
- 系统:Windows 10/11 或 Linux(Ubuntu/CentOS)
- 工具链:Visual Studio(Windows)/ GCC(Linux)
- CUDA Toolkit:建议选择稳定版(如 11.8 / 12.2)
2.2 Windows 安装步骤
- 查看显卡支持的最高 CUDA 版本
cmd
nvidia-smi - 下载对应版本 CUDA Toolkit 并安装(建议自定义安装,只保留核心组件)
- 配置环境变量:确保
CUDA_PATH、Path包含bin、lib\x64 - 验证安装
cmd
nvcc -V
出现版本信息即安装成功。
2.3 Linux 简易安装
bash
运行
wget https://developer.download.nvidia.com/compute/cuda/12.2.0/local_installers/cuda_12.2.0_535.54.03_linux.run
sudo sh cuda_12.2.0_535.54.03_linux.run
配置环境变量:
bash
运行
export PATH=/usr/local/cuda-12.2/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-12.2/lib64:$LD_LIBRARY_PATH
三、CUDA 核心编程模型
3.1 基本概念
- Host:CPU + 主机内存
- Device:GPU + 显存
- Kernel:GPU 上执行的并行函数,由
__global__修饰 - Thread:最小执行单元
- Block:线程块,内部线程可同步、共享局部内存
- Grid:多个 Block 组成一个网格
3.2 执行模型
调用格式:
cpp
运行
kernel<<<GridDim, BlockDim>>>(参数...);
常用配置:
- 一维:
<<<N, 256>>> - Block 大小常用:32/64/128/256/512(32 的倍数)
3.3 常用内置变量
cpp
运行
threadIdx.x // 线程在Block内的ID
blockIdx.x // Block在Grid内的ID
blockDim.x // 每个Block的线程数
gridDim.x // Grid的Block数
四、第一个 CUDA 程序:向量加法
4.1 完整代码(vector_add.cu)
cpp
运行
#include <iostream>
#include <cstdio>
// CUDA内核函数:向量加法
__global__ void vectorAdd(const float *a, const float *b, float *c, int n) {
int i = blockIdx.x * blockDim.x + threadIdx.x;
if (i < n) {
c[i] = a[i] + b[i];
}
}
int main() {
const int N = 1024;
const size_t size = N * sizeof(float);
// 主机端内存
float *h_a = new float[N];
float *h_b = new float[N];
float *h_c = new float[N];
// 初始化数据
for (int i = 0; i < N; i++) {
h_a[i] = i * 1.0f;
h_b[i] = i * 2.0f;
}
// 设备端内存
float *d_a, *d_b, *d_c;
cudaMalloc(&d_a, size);
cudaMalloc(&d_b, size);
cudaMalloc(&d_c, size);
// 数据拷贝 Host -> Device
cudaMemcpy(d_a, h_a, size, cudaMemcpyHostToDevice);
cudaMemcpy(d_b, h_b, size, cudaMemcpyHostToDevice);
// 启动内核
int blockSize = 256;
int gridSize = (N + blockSize - 1) / blockSize;
vectorAdd<<<gridSize, blockSize>>>(d_a, d_b, d_c, N);
// 等待执行完成
cudaDeviceSynchronize();
// 结果拷贝 Device -> Host
cudaMemcpy(h_c, d_c, size, cudaMemcpyDeviceToHost);
// 输出前10项
for (int i = 0; i < 10; i++) {
printf("%.2f + %.2f = %.2f\n", h_a[i], h_b[i], h_c[i]);
}
// 释放内存
delete[] h_a;
delete[] h_b;
delete[] h_c;
cudaFree(d_a);
cudaFree(d_b);
cudaFree(d_c);
return 0;
}
4.2 编译运行
Windows(VS 新建 CUDA 项目)Linux:
bash
运行
nvcc vector_add.cu -o vec_add
./vec_add
五、CUDA 内存模型与优化
5.1 内存层次(速度从快到慢)
- 寄存器:线程私有,极快
- 共享内存(shared):Block 内共享,延迟低
- 常量内存(constant):只读,全局缓存
- 全局内存(Global Memory):容量最大,访问延迟高
5.2 常用内存操作 API
cpp
运行
cudaMalloc() // 分配显存
cudaMemcpy() // 数据传输
cudaFree() // 释放显存
__shared__ type var; // 定义共享内存
5.3 基础优化原则
- 减少 CPU-GPU 数据拷贝,这是最大性能瓶颈
- 使用共享内存做数据复用与合并访问
- 保证全局内存对齐访问、连续访问
- Block 大小设置为 32 的倍数( warp 大小 = 32)
六、常用调试与性能工具
6.1 错误检查
建议封装宏:
cpp
运行
#define CHECK_CUDA_ERROR(err) \
if (err != cudaSuccess) { \
printf("%s:%d error:%s\n", __FILE__, __LINE__, cudaGetErrorString(err)); \
exit(-1); \
}
6.2 常用工具
nvprof/ncu:性能分析- NVIDIA Nsight:VS/VStudio 集成调试
nvidia-smi:查看 GPU 状态、占用、算力
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐




所有评论(0)