本文将指导如何在 Linux 系统中实现 GPU 内存的共享,主要面向需要跨进程或跨用户共享 GPU 资源的场景。
操作前的准备
在开始之前,请确保您的系统满足以下条件:
- 安装了支持 CUDA 或 ROCm 的 NVIDIA 或 AMD GPU
- 已安装对应的驱动程序和计算框架(如 CUDA Toolkit 或 ROCm)
- 系统内核支持 /dev/mem 设备访问(通常需要 root 权限)
- 至少有两个需要共享 GPU 内存的进程或用户
详细操作指南
1. 安装必要的依赖
根据您的 GPU 类型选择相应的软件包。
sudo apt update
sudo apt install -y cuda-toolkit-11-8 # 以 NVIDIA CUDA 为例
2. 配置 GPU 共享

2.1 NVIDIA GPU 共享
使用 NVIDIA 的 nsys 工具可以简化共享配置。
sudo apt install -y nsys
nsys profile -o profile_output --stats=true ./your_gpu_app
对于手动配置,需要设置环境变量:
export CUDA_VISIBLE_DEVICES=0,1
2.2 AMD GPU 共享
AMD GPU 共享通常通过 ROCm 实现。
source /opt/rocm/5.0.1/env.sh
export HIP_VISIBLE_DEVICES=0,1
3. 使用共享内存的示例代码
以下是一个简单的 CUDA 示例,展示如何在不同进程间共享 GPU 内存。
#include <cuda_runtime.h>
#include <stdio.h>
__global__ void copy_kernel(float *dest, float *src, int n) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < n) {
dest[idx] = src[idx];
}
}
int main() {
const int N = 1024;
float h_src[N], h_dest[N];
float *d_src, *d_dest;
// 初始化数据
for (int i = 0; i < N; i++) {
h_src[i] = i;
}
// 分配 GPU 内存
cudaMalloc((void**)&d_src, N * sizeof(float));
cudaMalloc((void**)&d_dest, N * sizeof(float));
// 复制数据到 GPU
cudaMemcpy(d_src, h_src, N * sizeof(float), cudaMemcpyHostToDevice);
// 启动内核
int threadsPerBlock = 256;
int blocksPerGrid = (N + threadsPerBlock - 1) / threadsPerBlock;
copy_kernel<<>>(d_dest, d_src, N);
// 复制结果回 CPU
cudaMemcpy(h_dest, d_dest, N * sizeof(float), cudaMemcpyDeviceToHost);
// 验证结果
for (int i = 0; i < N; i++) {
if (h_dest[i] != h_src[i]) {
printf("Error at index %d\n", i);
return 1;
}
}
printf("Success!\n");
// 释放资源
cudaFree(d_src);
cudaFree(d_dest);
return 0;
}
4. 使用 /dev/mem 直接访问 GPU 内存(高级用法)
此方法需要 root 权限,仅适用于特定场景。
sudo cat /dev/mem | grep -A 100000 000000000000... # 查看设备内存
sudo mknod /dev/gpu mem c 241 0 # 创建 GPU 内存设备节点(以 NVIDIA T4 为例)
关键命令解释
- CUDA_VISIBLE_DEVICES: 控制哪些 GPU 对当前进程可见
- nsys: NVIDIA 性能分析工具,可用于监控 GPU 共享状态
- hip_visible_devices: ROCm 环境变量,类似 CUDA_VISIBLE_DEVICES
- cudaMalloc: 在 GPU 上分配内存
- cudaMemcpy: 在 CPU 和 GPU 之间复制内存
注意事项和技巧
- GPU 共享可能导致性能下降,因为需要协调多个进程对同一资源的访问
- 对于 CUDA,建议使用 cudaSetDevice 显式指定使用的 GPU
- 使用 cudaDeviceSynchronize 确保所有操作完成后再进行下一步
- 避免在共享环境中频繁使用 cudaDeviceReset,这会导致所有 GPU 资源被释放
- 如果遇到内存访问错误,检查 /var/log/Xorg.0.log 或 journalctl 获取更多信息