0
我正在寻找一个函数来重新分配CUDA(设备)数组,如果数据超过它的容器。背景是稀疏的数据,我保存在数组中,我从0开始缓慢地开始填充。函数重新分配在cuda中增长的内存
我开始了一个分配给定数量的开始:
在的main():
int number_of_blocks = 30;
int dyn_cells = number_of_blocks * (BLOCK_WIDTH-4) * (BLOCK_HEIGHT-4);
HANDLE_ERROR(cudaMalloc(&h_dev, dyn_cells * sizeof(float)));
我然后做了一些计算,越来越多的在h_dev块的习惯了。如果其中一半以上被使用,我想让阵列变大。我用这个功能来做到这一点:
void grow_array(float **ptr, int length, int length_new)
{
float *ptr_new;
int width = length_new * (BLOCK_WIDTH - 4);
int height= (BLOCK_HEIGHT- 4);
HANDLE_ERROR(cudaMalloc(&ptr_new , width * height * sizeof(float)));
//this is the copy kernel
dim3 threads(BLOCK_WIDTH-4,BLOCK_HEIGHT-4);
dim3 blocks(length_new);
copy_kernel<<<blocks,threads>>>(*ptr,ptr_new, length, length_new);
float *old_ptr;
old_ptr = *ptr;
HANDLE_ERROR(cudaFree(old_ptr));
*ptr = ptr_new;
}
我称之为是这样的:
void memory_manager(int &blocks_available, int blocks_used, float** h_dev)
{
double ratio = (double)blocks_used/(double)blocks_available;
if (ratio > 0.5)
{
int new_length = 1.5 * blocks_available;
grow_array(h_dev , blocks_available, new_length);
(...)
{
{
复制内核看起来如下:
__global__ void copy_kernel(float* old_vector, float* new_vector, int old_size, int new_size)
{
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = threadIdx.y;
int offset_new = x + y * new_size * (BLOCK_WIDTH-4);
int offset_old = x + y * old_size * (BLOCK_WIDTH-4);
if (blockIdx.x < old_size)
{
new_vector[offset_new] = old_vector[offset_old];
}
else
{
new_vector[offset_new] = 42.0f;
}
}
我最初写这个原型后其中使用了malloc和免费(非CUDA)这似乎工作。但是,这会让我的程序崩溃,并提示超出内存访问范围。我很确定我缺少一些参考/解引用问题,但无法找到问题的确切位置。任何指向为什么会失败的指针?
您可能需要显示*全部*相关代码。例如,启动一个2-D线程块的一维网格看起来很奇怪。你当然可以做到这一点,但它会引发一些问题,你如何计算你没有显示的'copy_kernel'中的索引。如果它是您所指的设备越界地址,则最好显示设备代码。你能更清楚地说明“让我的程序崩溃”吗?这是否意味着seg故障,或其他?你尝试过'cuda-memcheck'吗?请显示其他人可以编译和运行的* complete *应用程序。是的,这需要努力。 –
[这是我的尝试](http://pastebin.com/8HeBCv4b)围绕你所展示的内容('grow_array'和'memory_manager')构建一个代码。它似乎工作正常。如果您需要帮助,请提供*完整*示例,就像我所做的那样。投票结束。 –
亲爱的克罗维拉先生,感谢您抽出时间发表评论。我已经包含了有关复制内核的问题。我没有添加它,因为在另一个内核中出现越界错误,如果我工作在“静态”大小的内存上,它工作正常。这让我相信代码的内存管理部分可能存在一个明显的错误。 –