复制到malloc()分配的全局内存?

时间:2012-09-03 15:24:24

标签: pointers memory-management cuda

CUDA编程指南指出“通过malloc()分配的内存可以使用运行时复制(即通过调用设备内存中的任何复制内存函数)”,但不知怎的,我无法重现这一点功能。代码:

#include <cstdio>
__device__ int* p;

__global__ void allocate_p() {
  p = (int*) malloc(10);
  printf("p = %p  (seen by GPU)\n", p);
}

int main() {
  cudaError_t err;
  int* localp = (int*) malloc(10);

  allocate_p<<<1,1>>>();
  cudaDeviceSynchronize();

  //Getting pointer to device-allocated memory
  int* tmpp = NULL;
  cudaMemcpyFromSymbol(&tmpp, p, 4);
  printf("p = %p  (seen by CPU)\n", tmpp);

  //cudaMalloc((void**)&tmpp, 40);
  err = cudaMemcpy(tmpp, localp, 40, cudaMemcpyHostToDevice);
  cudaDeviceSynchronize();
  printf(" err:%i %s", (int)err, cudaGetErrorString(err));

  delete localp;
  return 0;
}

输出崩溃:

p = 0x601f920  (seen by GPU)
p = 0x601f920  (seen by CPU)
 err:11 invalid argument

我收集说,主持人在设备上看到了合适的地址,但不知道它是不是来自malloc()

如果我先由cudaMalloc((void**)&np, 40);分配,然后将指针np作为参数传递给内核allocate_p,那么它将被分配到p(而不是{{1}然后代码运行正常。

我做错了什么/如何在主机端功能中使用malloc()分配的设备内存?

1 个答案:

答案 0 :(得分:3)

据我所知,无法使用主机API函数复制运行时堆内存。在CUDA 4.x中肯定是不可能的,并且CUDA 5.0发布候选版本没有改变这一点。我可以提供的唯一解决方法是使用内核“收集”最终结果并将它们填充到设备传输缓冲区或零拷贝内存中,可以通过API或直接从主机访问。您可以在this answeranother question中看到此方法的示例,其中来自NVIDIA的Mark Harris确认这是CUDA运行时(当时)当前实现的限制。