我知道cudaMemcpy会同步主机和设备,但cudaMalloc或cudaFree怎么样?
基本上我想在多个GPU设备上异步内存分配/复制和内核执行,我的代码的简化版本是这样的:
void wrapper_kernel(const int &ngpu, const float * const &data)
{
cudaSetDevice(ngpu);
cudaMalloc(...);
cudaMemcpyAsync(...);
kernels<<<...>>>(...);
cudaMemcpyAsync(...);
some host codes;
}
int main()
{
const int NGPU=3;
static float *data[NGPU];
for (int i=0; i<NGPU; i++) wrapper_kernel(i,data[i]);
cudaDeviceSynchronize();
some host codes;
}
但是,GPU按顺序运行,无法找到原因。
答案 0 :(得分:1)
尝试为每个GPU使用cudaStream_t
。下面是从CUDA样本中获取的simpleMultiGPU.cu。
//Solver config
TGPUplan plan[MAX_GPU_COUNT];
//GPU reduction results
float h_SumGPU[MAX_GPU_COUNT];
....memory init....
//Create streams for issuing GPU command asynchronously and allocate memory (GPU and System page-locked) for (i = 0; i < GPU_N; i++)
{
checkCudaErrors(cudaSetDevice(i));
checkCudaErrors(cudaStreamCreate(&plan[i].stream));
//Allocate memory checkCudaErrors(cudaMalloc((void **)&plan[i].d_Data, plan[i].dataN * sizeof(float)));
checkCudaErrors(cudaMalloc((void **)&plan[i].d_Sum, ACCUM_N * sizeof(float)));
checkCudaErrors(cudaMallocHost((void **)&plan[i].h_Sum_from_device, ACCUM_N * sizeof(float)));
checkCudaErrors(cudaMallocHost((void **)&plan[i].h_Data, plan[i].dataN * sizeof(float)));
for (j = 0; j < plan[i].dataN; j++)
{
plan[i].h_Data[j] = (float)rand() / (float)RAND_MAX;
}
}
....kernel, memory copyback....
和here's使用multi gpu的一些指南。
答案 1 :(得分:1)
您看到 GPU 操作按顺序运行的最可能原因是 cudaMalloc
是异步的,但 cudaFree
不是(只需将它们排在 CPU 线程上,并在系列操作)。
您需要使用 pinned memory 进行从 CPU 内存到 GPU 内存的异步传输,Cuda 提供了两个实用函数 cudaMallocHost
和 cudaFreeHost
(而不是 malloc
和 free
) .顺便说一句,还有 cudaHostAlloc
用于更好的控制,请阅读 CUDA 手册了解详情。