多个cudaMemPrefetchAsync在Pascal GPU上运行时导致分段错误

时间:2016-10-13 21:00:06

标签: c++ cuda nvidia nvcc

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不实用。我做错了什么?

0 个答案:

没有答案