5、CUDA环境配置:CUDA版本确认、环境变量设置、nvcc编译器验证、CUDA Samples编译测试
好,咱们接着往下走。JetPack刷完机,系统起来了,第一件事是什么?我个人习惯,不是急着跑Demo,而是先把CUDA环境摸清楚。你想想看,Jetson上所有加速的根基就是CUDA,这玩意儿要是没配好,后面跑什么模型都是空中楼阁。
这一节,我带你亲手把CUDA环境捋一遍。从版本确认到环境变量,再到编译器验证,最后跑几个Sample看看效果。每一步我都会告诉你为什么要这么做,以及我在项目中踩过的坑。
5.1 确认CUDA版本——别信文档,信命令行
很多同学拿到板子,第一反应是去翻官方文档看CUDA版本。我的建议是:别信文档,信命令行。文档可能没更新,但系统里的东西骗不了人。
打开终端,敲下面这条命令:
cat /usr/local/cuda/version.txt
或者用这个:
nvcc --version
如果一切正常,你会看到类似这样的输出:
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2023 NVIDIA Corporation
Built on Wed_Nov_22_10:17:15_PST_2023
Cuda compilation tools, release 12.2, V12.2.140
这里有个细节要注意:nvcc --version 显示的是CUDA工具包的版本,而 cat /usr/local/cuda/version.txt 显示的是CUDA运行时版本。正常情况下两者应该一致。如果不一致?嗯,那说明你的环境变量可能有问题,或者装了多个版本的CUDA。
nvcc --version 显示11.4,但 cat /usr/local/cuda/version.txt 显示12.2。查了半天,发现是系统里残留了旧版本的CUDA符号链接。解决办法很简单:sudo rm /usr/local/cuda 然后重新创建软链接指向正确的版本。
5.2 环境变量设置——让系统找到CUDA
确认版本没问题后,下一步就是设置环境变量。说白了,就是告诉系统:「CUDA装在这儿,编译器、链接器都往这儿找」。
我个人习惯把环境变量写在 ~/.bashrc 里,这样每次打开终端自动生效。打开文件:
nano ~/.bashrc
在文件末尾添加以下内容:
export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
export CUDA_HOME=/usr/local/cuda
保存退出后,执行 source ~/.bashrc 让配置生效。
这里我多说一句:CUDA_HOME 这个变量不是必须的,但很多第三方库(比如OpenCV、TensorRT)会用到它。提前设好,省得后面编译时到处报错。
echo $PATH 检查环境变量是否生效。如果看到 /usr/local/cuda/bin 出现在路径里,说明设置成功了。
5.3 nvcc编译器验证——写个Hello World试试
环境变量配好了,接下来验证编译器能不能正常工作。写一个最简单的CUDA程序,我管它叫「CUDA版的Hello World」。
创建一个文件 test.cu:
#include <stdio.h>
__global__ void hello_from_gpu() {
printf("Hello from GPU block %d, thread %d\n", blockIdx.x, threadIdx.x);
}
int main() {
hello_from_gpu<<<2, 4>>>();
cudaDeviceSynchronize();
return 0;
}
然后编译:
nvcc -o test test.cu
如果编译成功,运行 ./test,你会看到:
Hello from GPU block 0, thread 0
Hello from GPU block 0, thread 1
Hello from GPU block 0, thread 2
Hello from GPU block 0, thread 3
Hello from GPU block 1, thread 0
Hello from GPU block 1, thread 1
Hello from GPU block 1, thread 2
Hello from GPU block 1, thread 3
看到这个输出,说明你的nvcc编译器没问题,GPU也能正常调用。为什么是2个block、每个block 4个线程?因为我在 <<<2, 4>>> 里就是这么指定的。你想想看,这就是CUDA的线程层次结构——grid、block、thread,一目了然。
fatal error: cuda_runtime.h: No such file or directory,说明你的环境变量没配好,或者CUDA安装路径不对。回去检查 PATH 和 LD_LIBRARY_PATH。
5.4 CUDA Samples编译测试——跑官方例程更放心
自己写的Hello World跑通了,但还不够。我建议你把NVIDIA官方提供的CUDA Samples也编译一遍。这些Sample覆盖了CUDA的各个功能模块,能帮你全面验证环境。
Samples通常安装在 /usr/local/cuda/samples 目录下。先把它拷贝到用户目录,避免权限问题:
cp -r /usr/local/cuda/samples ~/cuda-samples
cd ~/cuda-samples
然后编译:
make -j4
这个过程会编译所有Sample,大概需要几分钟。编译完成后,进入 bin/ 目录,你会看到一堆可执行文件。
我推荐先跑这几个:
| Sample名称 | 测试内容 | 运行命令 |
|---|---|---|
| deviceQuery | 查看GPU设备信息 | ./deviceQuery |
| bandwidthTest | 测试显存带宽 | ./bandwidthTest |
| simplePrintf | GPU端printf功能 | ./simplePrintf |
| simpleTemplates | CUDA模板编程 | ./simpleTemplates |
运行 deviceQuery 时,你会看到Jetson的GPU详细信息,包括计算能力(Compute Capability)、显存大小、SM数量等。这些信息在后面调优时非常有用。
make 过程中报错,别慌。常见错误是缺少依赖库,比如 libGL.so 或 libX11.so。用 sudo apt-get install 补上就行。我曾经在Jetson Xavier NX上遇到过 libEGL.so 找不到的问题,装个 libegl1-mesa-dev 就解决了。
5.5 知识体系梳理
这一节的内容,说白了就是四个步骤:确认版本 → 设置环境 → 验证编译器 → 跑官方例程。它们之间的关系我画了张图,你看一眼就明白了:
这张图把整个流程串起来了。你按这个顺序走一遍,基本上不会出大问题。如果中间某一步卡住了,别硬撑,回头检查上一步——八成是环境变量没配好,或者版本对不上。
5.6 避坑总结
最后,我把这些年踩过的坑总结一下,你遇到了可以直接对照:
- nvcc找不到:检查
PATH里有没有/usr/local/cuda/bin,没有就加上。 - 编译时报错缺少头文件:检查
LD_LIBRARY_PATH是否包含/usr/local/cuda/lib64。 - 运行Sample时报段错误:大概率是显存不足。Jetson的共享内存有限,别一次开太多线程。
- deviceQuery显示GPU为0:检查是否安装了正确的驱动,或者Jetson是否处于MAXN模式。
嗯,CUDA环境配置就讲到这里。你按我说的步骤走一遍,应该半小时内就能搞定。配置好了之后,下一节我们就可以开始玩TensorRT了——那才是真正有意思的东西。
公众号:蓝海资料掘金营,微信deep3321