如current_time()
中所述,当cudaMallocManaged与Pascal GPU一起使用时,需要cudaMemPrefetchAsync以确保更好的性能。问题是如果内核中使用多个内存需要多次cudaMemPrefetchAsync调用,它将返回分段错误。
以下代码正常运行
__global__ static void CUDAKernelAddOneToVector(int *data, int *data2){
const int x = blockIdx.x * blockDim.x + threadIdx.x;
const int y = blockIdx.y * blockDim.y + threadIdx.y;
const int mx = gridDim.x * blockDim.x;
data[y * mx + x] = data[y * mx + x] + 1;
data2[y * mx + x] = data2[y * mx + x] + 1;
}
void AddOneToVector(std::vector<int> &in){
int *data;
int *data2;
cudaMallocManaged(reinterpret_cast<void **>(&data),
in.size() * sizeof(int),
cudaMemAttachGlobal);
cudaMallocManaged(reinterpret_cast<void **>(&data2),
in.size() * sizeof(int),
cudaMemAttachGlobal);
cudaMemcpy(data,in.data(),in.size()*sizeof(int),cudaMemcpyHostToHost);
cudaMemcpy(data2,in.data(),in.size()*sizeof(int),cudaMemcpyHostToHost);
dim3 blks(in.size()/(16*32),1);
dim3 threads(32, 16);
cudaMemPrefetchAsync(data, in.size() * sizeof(int), 0);
cudaMemPrefetchAsync(data2, in.size() * sizeof(int), 0);
CUDAKernelAddOneToVector<<<blks, threads>>>(data,data2);
cudaDeviceSynchronize();
cudaMemcpy(in.data(),data,in.size()*sizeof(int),cudaMemcpyHostToHost);
cudaFree(data);
}
但是,如果代码变为
{{1}}
仅在Pascal GPU上运行时才返回分段错误。完全相同的代码在Maxwell GPU上运行良好。如果我注释掉第二个cudaMemPrefetchAsync并让Pascal为data2执行按需内存分页,那么它运行正常。无法为多个内存运行cudaMemPrefetchAsync使得在Pascal GPU上使用cudaMallocManaged不实用。我做错了什么?