【发布时间】:2014-10-15 16:03:38
【问题描述】:
根据this question和引用NVIDIA CUDA Programming Guide,realloc功能没有实现:
内核中的 CUDA 函数
malloc()至少分配了size字节 从设备堆中返回一个指向已分配内存的指针或 如果没有足够的内存来满足请求,则为 NULL。这 返回的指针保证与 16 字节边界对齐。内核中的 CUDA
free()函数释放指向的内存 由ptr提供,它必须是由先前对malloc()的调用返回的。 如果ptr为NULL,则忽略对free()的调用。反复调用free()与相同的ptr具有未定义的行为。
我现在被 GMP 库的某些部分困住了(或者更严格地说,我尝试将它移植到 CUDA 上),它依赖于这个功能:
__host__ __device__ static void * // generate this function for both CPU and GPU
gmp_default_realloc (void *old, size_t old_size, size_t new_size)
{
mp_ptr p;
#if __CUDA_ARCH__ // this directive separates device and host code
/* ? */
#else
p = (mp_ptr) realloc (old, new_size); /* host code has realloc from glibc */
#endif
if (!p)
gmp_die("gmp_default_realoc: Virtual memory exhausted.");
return p;
}
基本上我可以只需简单地用new_size 调用malloc,然后调用memcpy(或者可能是memmove),然后调用free 上一个块,但这需要强制移动数据(大型数组),我想避免。
是否有任何有效 有效方式来实现(标准 C 或 C++)realloc 函数(即内核内部)?假设我有一些动态分配的大数据数组(已经由 malloc 分配),然后在其他地方调用 realloc 以便为 那个 块请求更多的内存.简而言之,我想避免将整个数据数组复制到新位置,我特别询问如何做到这一点(当然,如果可能的话)。
我对 PTX ISA 或内核堆函数的底层实现并不是特别熟悉,但也许值得研究一下这个方向?
【问题讨论】:
-
realloc将copy data in some cases。如果您的问题是我如何在没有数据副本的情况下实现realloc(任何地方),对于一般情况,我认为它无法完成。你的问题到底是什么? 有效这个词并没有真正告诉我。换句话说,您的问题标题是:“在不移动数据的情况下在 CUDA 中实现 realloc”我会问您可以在主机上执行此操作吗?因为realloc不保证这一点。 -
我的意思是当我已经有一些大数据块(更准确地说是数组,例如
unsigned long对象),然后realloc用于获取更多内存。这只是artibratry精度数字的情况,无法确定需要多少内存。我知道 C99/C11 标准不保证数据会被保留,但通常情况下是这样。 -
如果您要求更大的内存,
realloc经常需要进行数据复制。我认为这种说法值得怀疑:“我知道 C99/C11 标准不能保证数据被保存,但通常情况下是这样的”。即使这是真的,在某些情况下,也不是所有情况都可以处理(即使在主机代码中)而不需要数据副本。因此,无论您是在谈论主机还是 GPU,我都怀疑您的问题是可能的(在没有数据副本的情况下实现 realloc)。 -
我再说一遍:在 c 或 c++ 标签上问这个问题:“如何在不移动数据的情况下实现 realloc?”无论您想出什么答案,都可能对创建 GPU 版本具有指导意义。我认为没有人可以在那里(或者)给你答案,但我可能是错的。
-
我认为你的观点是正确的。从
malloc、calloc或realloc分配的块都必须连续,并且没有什么真正保证更大的块将“适合”到可用的可用空间中(这以同样的方式影响主机和设备内存)。