CUDA 真的没有类似 calloc() 的 API 调用吗?

Posted

技术标签:

【中文标题】CUDA 真的没有类似 calloc() 的 API 调用吗?【英文标题】:Does CUDA really not have a calloc()-like API call? 【发布时间】:2014-01-20 12:10:51 【问题描述】:

从CUDA 5.5 API Reference 和CUDA C Programming Guide 看来,似乎没有cudaCalloc(),在GPU 上相当于标准C 库的calloc()

真的没有用于分配初始化为全零的缓冲区的 API 功能吗? 有什么比拨打cudaMalloc() 然后cudaMemset() 更好的办法吗?

【问题讨论】:

编译器库可能将 calloc 实现为 malloc + memset 的包装器。 @Lundin:我会说可能不会。您可以分配归零的内存块而无需实际设置任何数据,只需将块标记为空(例如,未从虚拟内存映射到物理内存,写入它们会导致页面错误)。当然,这取决于您使用的是什么机器。我不确定 GPU 上的内存归零是如何发生的,但很可能你可以做得比 malloc+memset 更好。 使用thrust::device_vector @JaredHoberock:你能回答这个问题并解释为什么在这种情况下使用thrust::device_vector 是一个好主意吗? 下面的答案有没有让你满意的?如果是,请接受。你有扔石头藏手的坏习惯。 【参考方案1】:

真的没有用于分配初始化为全零的缓冲区的 API 功能吗?

真的没有。

我可以在 cudaMalloc() 之后执行 cudaMemset() 吗?

如果为了方便起见,您可以使用宏(如果第一个问题的答案是否定的,您还没有告诉我们您所说的更好是什么意思):

#define cudaCalloc(A, B, C) \
    do  \
        cudaError_t __cudaCalloc_err = cudaMalloc(A, B*C); \
        if (__cudaCalloc_err == cudaSuccess) cudaMemset(*A, 0, B*C); \
     while (0)

上面的宏可以和我通常做的那种错误检查一起工作(它基于使用cudaGetLastError();或者如果你愿意,你可以直接在宏中构建你喜欢的错误检查。有关错误,请参阅this question处理。

【讨论】:

重新审视您的答案 - 为什么使用宏而不是标记为 inline 的函数? 你可以这样做。 我可能在想,在我们更加文明的时代(好吧,无论如何编程),最好编辑你的答案来推荐它。除非绝对必要 IMO,否则不应鼓励使用宏。顺便说一句,Nikolay Sakharnykh 打招呼。或者更确切地说,我提到了你的名字,他承认了:-) 为什么不添加答案?然后,您将因更加文明而受​​到赞誉。我会赞成。你甚至可以不接受这个并接受你自己的。【参考方案2】:

如果您想要的只是一种将新分配归零的简单方法,您可以使用thrust::device_vector,它默认构造其元素。对于原始类型,这与calloc 的行为相同。

【讨论】:

【参考方案3】:

CUDA 运行时 API 中没有类似 calloc() 的功能,也没有其他较低级别的等效功能。相反,您可以执行以下操作:

cudaMalloc(&ptr, size);
cudaMemset(ptr, 0, size);

请注意,这都是同步的。还有一个cudaMemsetAsync(),虽然,坦率地说,cudaMalloc()s 目前速度很慢,这并不重要。

【讨论】:

我认为使用 Memcpy 将缓冲区归零是一个相当糟糕的主意。 cudaMemset() 无论如何都会与主机异步运行(请参阅ref manual)。 不正确,该函数在大多数情况下都表现出同步行为【参考方案4】:

这是一个带有内联函数的解决方案。 devPtr 应该是指向任何东西的指针。使用void* 作为函数参数会从applying a cast 释放调用者。

inline cudaError_t
_cuda_calloc( void *devPtr, size_t size )

  cudaError_t err = cudaMalloc( (void**)devPtr, size );
  if( err == cudaSuccess ) err = cudaMemset( *(void**)devPtr, 0, size );
  return err;

【讨论】:

已经推荐了。

以上是关于CUDA 真的没有类似 calloc() 的 API 调用吗?的主要内容,如果未能解决你的问题,请参考以下文章

calloc函数的使用和对内存free的认识

在编写类似的 CUDA 内核时如何不重复自己没有宏?

为啥 Cuda/OpenCL 的全局内存中没有银行冲突?

类似py2exe软件真的能保护python源码吗

使用 CUDA 创建链表

为 CPU 编译 cuda 代码