第一章:CUDA简介与环境搭建

GPU计算概述——为什么我们需要它?

说实话,我第一次接触GPU计算时,心里也犯嘀咕:CPU不是挺好的吗?干嘛非要折腾GPU?

后来我在一个图像处理项目里被现实狠狠教育了一回。一张4K图片的像素点有800多万个,用CPU逐个处理,那速度简直让人抓狂。你想想看,CPU就像一辆法拉利,跑得飞快,但它一次只能拉一个人。而GPU呢?它像一辆大巴车,速度没那么夸张,但一次能拉几百号人。

这就是GPU计算的核心思想——并行计算。CPU擅长处理复杂的逻辑任务,GPU则擅长处理大量相同类型的简单运算。说白了,就是「人多力量大」。

核心概念:GPU计算(GPGPU,General-Purpose computing on Graphics Processing Units)就是利用GPU强大的并行计算能力,去解决原本由CPU处理的通用计算问题。它特别适合数据并行、计算密集型的任务。

我习惯把GPU计算的应用场景分成三类:

  • 图像与视频处理:滤波、变换、编解码——每个像素独立运算,天然适合并行
  • 科学计算与仿真:分子动力学、气象预报、流体力学——计算量大到CPU扛不住
  • 深度学习:矩阵乘法、卷积操作——这几乎是GPU的「主场」

CUDA架构——NVIDIA的「秘密武器」

CUDA是NVIDIA在2007年推出的并行计算平台和编程模型。我记得当时业内一片哗然——终于有人把GPU的「黑盒」打开了,让开发者可以直接用C语言写GPU程序。

CUDA架构有几个关键概念,我建议你牢牢记住:

概念 说明 我的理解
Host CPU及其内存系统 负责控制、调度、逻辑判断
Device GPU及其显存系统 负责大规模并行计算
Kernel 在GPU上执行的函数 用__global__修饰,由CPU调用
Thread 最小的执行单元 每个线程执行同一个kernel
Block 线程的集合 同一block内的线程可以共享内存
Grid block的集合 一个kernel对应一个grid

你可能会问:为什么要搞这么多层级?

嗯,这里有个关键点。GPU里有成百上千个计算核心,如果让开发者直接管理每个核心,那代码会变得极其复杂。CUDA通过「线程-块-网格」这种分层结构,把并行度管理的复杂性封装了起来。你只需要告诉CUDA「我要启动多少个线程」,剩下的硬件调度由它自动完成。

我的经验:刚开始学CUDA时,我总纠结于block和thread的具体数量。后来发现,先跑通再优化才是正道。默认用256个线程一个block,基本不会出大问题。

CUDA Toolkit安装——手把手教你配环境

安装CUDA Toolkit,说白了就是三步:下载、安装、配置环境变量。但我在项目中遇到过不少坑,这里给你列个避坑指南。

第一步:确认硬件兼容性

先看看你的NVIDIA显卡支不支持CUDA。在命令行里敲:

nvidia-smi

如果能看到显卡型号和驱动版本,恭喜你,硬件没问题。如果提示「命令未找到」,那就先去NVIDIA官网装驱动。

我曾经踩过的坑:有一次我直接在Ubuntu的软件源里装驱动,结果装完系统直接黑屏。后来学乖了,老老实实去NVIDIA官网下载.run文件手动安装。记住:永远不要用系统自带的驱动管理器装NVIDIA驱动。

第二步:下载并安装CUDA Toolkit

去NVIDIA开发者官网(developer.nvidia.com/cuda-downloads),选择你的操作系统和安装方式。我个人习惯用.run文件安装,因为可控性更强。

以Ubuntu 22.04为例:

wget https://developer.download.nvidia.com/compute/cuda/12.1.0/local_installers/cuda_12.1.0_530.30.02_linux.run
sudo sh cuda_12.1.0_530.30.02_linux.run

安装过程中会问你是否安装驱动——如果你已经装好了,就取消勾选「Driver」选项,只装Toolkit。

第三步:配置环境变量

安装完成后,把CUDA的bin和lib64目录加到PATH和LD_LIBRARY_PATH里。编辑~/.bashrc,在末尾加上:

export PATH=/usr/local/cuda-12.1/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-12.1/lib64:$LD_LIBRARY_PATH

然后source ~/.bashrc让它生效。验证一下:

nvcc --version

如果看到版本号,说明安装成功了。

小技巧:我习惯在/usr/local下创建一个软链接cuda指向当前版本,这样以后升级CUDA时,只需要改软链接,不用改环境变量。

nvcc编译器——CUDA程序的「翻译官」

nvcc是CUDA的编译器,它负责把.cu文件编译成可执行文件。你想想看,一个.cu文件里既有CPU代码(C++),又有GPU代码(CUDA C),nvcc需要把它们分开处理:

  • GPU代码 → 编译成PTX(并行线程执行)中间代码 → 再编译成cubin二进制
  • CPU代码 → 交给系统自带的C++编译器(如g++)处理

一个最简单的编译命令:

nvcc -o hello hello.cu

常用的编译选项我整理了一下:

选项 作用 我常用的场景
-arch=sm_86 指定GPU架构(如RTX 30系列是sm_86) 编译针对特定显卡优化的代码
-O2 优化等级 发布版本必加
-G 生成调试信息 调试阶段使用,但会降低性能
-lineinfo 保留行号信息 配合profiler分析性能时用

注意:如果你用-arch=sm_86编译的程序,放到GTX 1080(sm_61)上跑,会直接报错。我建议编译时用-arch=sm_61这种较低的版本号,兼容性更好。或者用-gencode选项生成多个架构的fatbin。

本章知识体系

下面这张图帮你理清本章的核心脉络:

CUDA简介与环境搭建 · 知识体系 GPU计算概述 为什么需要GPU计算? 并行计算 vs 串行计算 应用场景:图像/科学计算/深度学习 CPU=法拉利,GPU=大巴车 CUDA架构 Host(CPU)与 Device(GPU) Kernel 函数概念 线程层级:Thread → Block → Grid 共享内存与同步机制 CUDA Toolkit安装 Step 1:确认硬件兼容性(nvidia-smi) Step 2:下载并安装Toolkit Step 3:配置环境变量 验证:nvcc --version nvcc编译器 编译流程:.cu → PTX → cubin 常用选项:-arch / -O2 / -G 架构兼容性注意事项 nvcc -o hello hello.cu 打好基础,才能写出高效的CUDA程序

这张图把本章的四个核心模块串在了一起。从「为什么需要GPU计算」开始,到「CUDA架构」理解工作原理,再到「环境搭建」和「编译器使用」——每一步都是后续章节的基石。

我个人觉得,环境搭建这一步虽然枯燥,但值得认真对待。我见过太多同学卡在「Hello World」跑不通的环节,最后发现是环境变量没配好。嗯,磨刀不误砍柴工,把这一步走稳了,后面会顺畅很多。

可可精品资料库