共计 3124 个字符,预计需要花费 8 分钟才能阅读完成。
为什么选择 A100?
当第一次拿到 A100 显卡时,我对比了手头的 RTX 3090 测试数据:

| 指标 | A100 80GB | RTX 3090 |
|---|---|---|
| FP32 TFLOPS | 19.5 | 35.6 |
| FP64 TFLOPS | 9.7 | 0.56 |
| 显存带宽 | 2039GB/s | 936GB/s |
看起来游戏卡在单精度计算上更强?但 A100 的杀手锏在于:
- NVLink:6 块 A100 通过 NVLink 3.0 互联,带宽高达 600GB/s,比 PCIe 4.0 快 5 倍
- MIG 技术:可以将单卡物理分割成 7 个独立实例,每个实例有独立显存和计算单元
- Tensor Core:第三代 Tensor Core 支持 TF32 格式,自动混合精度下性能可达 312TFLOPS
环境配置实战(Ubuntu 20.04)
驱动安装
-
卸载旧驱动(如果有):
sudo apt purge nvidia* -
添加官方仓库:
distribution=$(. /etc/os-release;echo $ID$VERSION_ID | sed 's/\.//g') curl -s -L https://nvidia.github.io/libnvidia-container/gpgkey | sudo apt-key add - curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list -
安装 525 系列驱动:
sudo apt update sudo apt install -y nvidia-driver-525
验证安装:
nvidia-smi
应该看到类似输出:
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 525.60.13 Driver Version: 525.60.13 CUDA Version: 12.0 |
|-------------------------------+----------------------+----------------------+
CUDA Toolkit 12.x
-
下载网络安装包:
wget https://developer.download.nvidia.com/compute/cuda/12.0.1/local_installers/cuda_12.0.1_525.85.12_linux.run -
执行安装(注意加上 –toolkit 选项):
sudo sh cuda_12.0.1_525.85.12_linux.run --toolkit -
验证 nvcc:
nvcc --version
加速库兼容性
推荐组合版本:
| 组件 | 推荐版本 |
|---|---|
| cuDNN | 8.6.0 |
| TensorRT | 8.5.2 |
安装示例:
sudo apt install libcudnn8=8.6.0.*-1+cuda12.0
第一个 CUDA 程序:矩阵乘法
基础版本(全局内存)
__global__ void matmul_kernel(float *A, float *B, float *C, int N) {
int row = blockIdx.y * blockDim.y + threadIdx.y;
int col = blockIdx.x * blockDim.x + threadIdx.x;
if (row < N && col < N) {
float sum = 0.0f;
for (int k = 0; k < N; k++) {sum += A[row * N + k] * B[k * N + col];
}
C[row * N + col] = sum;
}
}
// 调用示例
void matmul(float *A, float *B, float *C, int N) {
float *d_A, *d_B, *d_C;
cudaMallocManaged(&d_A, N*N*sizeof(float));
cudaMallocManaged(&d_B, N*N*sizeof(float));
cudaMallocManaged(&d_C, N*N*sizeof(float));
// 拷贝数据...
dim3 blocks(N/16, N/16);
dim3 threads(16, 16);
matmul_kernel<<<blocks, threads>>>(d_A, d_B, d_C, N);
cudaDeviceSynchronize();}
共享内存优化版
__global__ void matmul_shared_kernel(float *A, float *B, float *C, int N) {__shared__ float s_A[16][16];
__shared__ float s_B[16][16];
int row = blockIdx.y * blockDim.y + threadIdx.y;
int col = blockIdx.x * blockDim.x + threadIdx.x;
float sum = 0.0f;
for (int tile = 0; tile < N/16; ++tile) {s_A[threadIdx.y][threadIdx.x] = A[row * N + (tile * 16 + threadIdx.x)];
s_B[threadIdx.y][threadIdx.x] = B[(tile * 16 + threadIdx.y) * N + col];
__syncthreads();
for (int k = 0; k < 16; k++) {sum += s_A[threadIdx.y][k] * s_B[k][threadIdx.x];
}
__syncthreads();}
if (row < N && col < N) {C[row * N + col] = sum;
}
}
性能对比(N=2048)
| 版本 | GFLOPS | 耗时(ms) |
|---|---|---|
| 全局内存 | 128.7 | 66.8 |
| 共享内存 | 1842.3 | 4.67 |
| cuBLAS | 9874.1 | 0.87 |
避坑指南
ECC 显存错误
当看到如下报错时:
CUDA error: uncorrectable ECC error encountered
解决方案:
-
检查显存状态:
nvidia-smi -q -d MEMORY -
临时禁用 ECC(不推荐):
sudo nvidia-smi --ecc-config=0
PCIe 拓扑优化
多 GPU 通信时,使用以下命令查看拓扑:
nvidia-smi topo -m
优化原则:
- 优先使用同 CPU 插槽下的 GPU 通信
- 跨 NUMA 节点时考虑使用 GPU Direct RDMA
混合精度 NaN 检测
在训练脚本中添加:
from torch.autograd import detect_anomaly
with detect_anomaly():
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
进阶思考
- 使用 Nsight Compute 分析时,重点关注:
- Stall Reasons > Warp Stall Reasons
-
Scheduler Statistics > Warp Cycles Per Issued
-
移植到 RTX 4090 需要调整:
- 将 FP64 计算改为 FP32 或 TF32
- 减少每个 SM 的线程块数量(4090 的 SM 数量比 A100 少)
- 利用新的 Ada 架构的 Tensor Memory Accelerator
总结
通过这个实战项目,我们实现了:
- 正确配置 A100 开发环境
- 编写了首个利用共享内存优化的 CUDA 核函数
- 掌握了基本的性能分析和调试方法
建议下一步尝试:
- 使用 CUDA Graphs 优化小规模 kernel 的启动延迟
- 尝试用 CUTLASS 库实现更高效的 GEMM
- 在 PyTorch 中使用
torch.compile体验自动优化
希望这篇指南能帮你快速上手 A100 的强大算力!
正文完
