GPU 编译器技术
GPU 编译器技术
GPU 编译器技术
GPU 编译器是现代并行计算的核心技术,负责将高级语言代码转换为GPU可执行的机器码。本章节深入探讨CUDA、OpenCL、ROCm等主流GPU编程模型的编译技术。
📋 章节概览
🎯 学习目标
通过本章节的学习,你将掌握:
- GPU 架构理解: 深入了解现代GPU的硬件架构
- 编译流程: 掌握GPU代码的完整编译过程
- 性能优化: 学会GPU程序的性能分析和优化
- 内存管理: 理解GPU内存层次和优化策略
- 并行模式: 掌握各种GPU并行编程模式
🏗️ GPU 编译器架构
CUDA 编译流程
CUDA C/C++ → [NVCC] → PTX → [Driver] → SASS
↓ ↓ ↓ ↓
源代码 前端编译 中间表示 机器码
OpenCL 编译流程
OpenCL C → [Clang] → SPIR-V → [Runtime] → ISA
↓ ↓ ↓ ↓ ↓
内核代码 前端编译 中间表示 运行时编译 机器码
ROCm 编译流程
HIP/OpenCL → [HCC/Clang] → AMDGCN → [ROCm] → GCN ISA
↓ ↓ ↓ ↓ ↓
源代码 前端编译 LLVM IR 后端编译 机器码
🔧 开发环境搭建
CUDA 开发环境
# 安装 CUDA Toolkit
wget https://developer.download.nvidia.com/compute/cuda/12.0.0/local_installers/cuda_12.0.0_525.60.13_linux.run
sudo sh cuda_12.0.0_525.60.13_linux.run
# 设置环境变量
export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
# 验证安装
nvcc --version
nvidia-smi
OpenCL 开发环境
# 安装 OpenCL 头文件和库
sudo apt-get install opencl-headers ocl-icd-opencl-dev
# 安装供应商特定的 ICD
# NVIDIA
sudo apt-get install nvidia-opencl-icd
# AMD
sudo apt-get install mesa-opencl-icd
# Intel
sudo apt-get install intel-opencl-icd
# 验证安装
clinfo
ROCm 开发环境
# 添加 ROCm 仓库
wget -qO - https://repo.radeon.com/rocm/rocm.gpg.key | sudo apt-key add -
echo 'deb [arch=amd64] https://repo.radeon.com/rocm/apt/debian/ ubuntu main' | sudo tee /etc/apt/sources.list.d/rocm.list
# 安装 ROCm
sudo apt update
sudo apt install rocm-dkms
# 设置环境变量
export PATH=/opt/rocm/bin:$PATH
export LD_LIBRARY_PATH=/opt/rocm/lib:$LD_LIBRARY_PATH
# 验证安装
rocminfo
hipcc --version
💻 第一个GPU程序
CUDA 示例
// vector_add.cu
#include <cuda_runtime.h>
#include <stdio.h>
__global__ void vectorAdd(float *a, float *b, float *c, int n) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < n) {
c[idx] = a[idx] + b[idx];
}
}
int main() {
const int N = 1024;
size_t size = N * sizeof(float);
// 分配主机内存
float *h_a = (float*)malloc(size);
float *h_b = (float*)malloc(size);
float *h_c = (float*)malloc(size);
// 初始化数据
for (int i = 0; i < N; i++) {
h_a[i] = i;
h_b[i] = i * 2;
}
// 分配设备内存
float *d_a, *d_b, *d_c;
cudaMalloc(&d_a, size);
cudaMalloc(&d_b, size);
cudaMalloc(&d_c, size);
// 拷贝数据到设备
cudaMemcpy(d_a, h_a, size, cudaMemcpyHostToDevice);
cudaMemcpy(d_b, h_b, size, cudaMemcpyHostToDevice);
// 启动内核
int threadsPerBlock = 256;
int blocksPerGrid = (N + threadsPerBlock - 1) / threadsPerBlock;
vectorAdd<<<blocksPerGrid, threadsPerBlock>>>(d_a, d_b, d_c, N);
// 拷贝结果回主机
cudaMemcpy(h_c, d_c, size, cudaMemcpyDeviceToHost);
// 验证结果
for (int i = 0; i < 10; i++) {
printf("c[%d] = %.2f\n", i, h_c[i]);
}
// 清理内存
free(h_a); free(h_b); free(h_c);
cudaFree(d_a); cudaFree(d_b); cudaFree(d_c);
return 0;
}
编译和运行
# 编译 CUDA 程序
nvcc -o vector_add vector_add.cu
# 运行程序
./vector_add
# 查看 PTX 中间代码
nvcc -ptx vector_add.cu
cat vector_add.ptx
# 查看 SASS 汇编代码
nvcc -cubin vector_add.cu
cuobjdump -sass vector_add.cubin
🚀 GPU 架构特点
SIMT 执行模型
Warp (32 threads)
├── Thread 0 ┐
├── Thread 1 │ 执行相同指令
├── Thread 2 │ (SIMT)
├── ... │
└── Thread 31 ┘
内存层次结构
全局内存 (Global Memory) - 大容量,高延迟
↑
共享内存 (Shared Memory) - 小容量,低延迟
↑
寄存器 (Registers) - 最快访问
↑
常量内存 (Constant Memory) - 只读,有缓存
纹理内存 (Texture Memory) - 只读,空间局部性优化
📊 性能分析工具
NVIDIA 工具链
# Nsight Compute - 内核性能分析
ncu --set full ./vector_add
# Nsight Systems - 系统级性能分析
nsys profile ./vector_add
# nvprof - 传统性能分析工具
nvprof ./vector_add
AMD 工具链
# ROCProfiler - AMD GPU 性能分析
rocprof ./hip_program
# ROCTracer - API 调用跟踪
roctracer ./hip_program