GDS简介
GPUDirect Storage(GDS)是NVIDIA推出的一项关键技术,用于实现GPU显存与兼容存储系统之间的直接数据通路,从而绕过CPU和系统内存拷贝。该技术旨在解决高性能计算与AI训练场景中,存储I/O可能成为整体性能瓶颈的问题。其主要优势包括:
降低数据访问延迟:缩短GPU等待数据的时间。
提高有效带宽:最大化GPU从存储读取和写入数据的吞吐量。
释放CPU资源:减少CPU在I/O路径上的介入,使其更专注于计算任务。
天翼云高性能并行文件服务HPFS已支持GPUDirect Storage技术。用户可在基于NVIDIA GPU的主机上,部署支持GDS的应用程序,并通过cuFile API直接访问HPFS文件系统。实测表明,相较于传统的POSIX API标准访问方式,此项优化可带来约30% 的吞吐性能提升,显著加速GPU数据处理流水线。
GDS原理
通过传统的POSIX API读取流程如下:
int fd = open(...)
void *sysmem_buf, *gpumem_buf;
sysmem_buf = malloc(buf_size);
cudaMalloc(gpumem_buf, buf_size);
pread(fd, sysmem_buf, buf_size);
cudaMemcpy(sysmem_buf, gpumem_buf, buf_size, H2D);
cuStreamSynchronize(0);使用GDS API可以绕过CPU直接从HPFS读取,使得数据不经过内存直接从HPFS复制GPU显存,大幅提升性能:
int fd = open(file_name, O_DIRECT,...)
CUFileHandle_t *fh;
CUFileDescr_t desc;
desc.type=CU_FILE_HANDLE_TYPE_OPAQUE_FD;
desc.handle.fd = fd;
cuFileHandleRegister(&fh, &desc);
void *gpumem_buf;
cudaMalloc(gpumem_buf, buf_size);
cuFileRead(&fh, gpumem_buf, buf_size, ...);开始使用
您需要根据硬件版本信息,在使用前在GPU客户端安装GDS,详细安装步骤请自行查询GPUDirect Storage Installation and Troubleshooting Guide。
以下是使用GDS的示例代码:
#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <cuda_runtime.h>
#include <cufile.h>
int main() {
CUfileHandle_t cfHandle;
CUfileDescr_t cfDescr = {};
const char *filename = "/mnt/hpfs/testfile";
int fd = open(filename, O_CREAT | O_RDWR, 0664);
if (fd < 0) {
perror("File open failed");
return 1;
}
// Set up GDS descriptor
cfDescr.handle.fd = fd;
cfDescr.type = CU_FILE_HANDLE_TYPE_OPAQUE_FD;
CUfileError_t status = cuFileHandleRegister(&cfHandle, &cfDescr);
if (status.err != CU_FILE_SUCCESS) {
std::cerr << "cuFileHandleRegister failed: " << status.err << std::endl;
close(fd);
return 1;
}
// Alloc GPU memory and fill GPU memory with data
void *devPtr;
size_t bufferSize = 8192;
cudaMalloc(&devPtr, bufferSize);
cudaMemset(devPtr, 0xAB, bufferSize);
// Perform the write
ssize_t writtenBytes = cuFileWrite(cfHandle, devPtr, bufferSize, 0, 0);
if (writtenBytes < 0) {
perror("cuFileWrite failed");
} else {
std::cout << "Wrote " << writtenBytes << " bytes to the file." << std::endl;
}
getBoolParameter()
// Clean up
cuFileHandleDeregister(cfHandle);
close(fd);
cudaFree(devPtr);
return 0;
}通过以下命令编译:
g++ -o gds_example gds_example.cc -I/usr/local/cuda/include -L/usr/local/cuda/lib64 -lcuda -lcufile -lcudart
更多的GDS API用法请您根据硬件版本自行查询 GDS cuFile API Reference。