2014-02-16 38 views
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

您可能需要显示*全部*相关代码。例如,启动一个2-D线程块的一维网格看起来很奇怪。你当然可以做到这一点,但它会引发一些问题,你如何计算你没有显示的'copy_kernel'中的索引。如果它是您所指的设备越界地址,则最好显示设备代码。你能更清楚地说明“让我的程序崩溃”吗?这是否意味着seg故障,或其他?你尝试过'cuda-memcheck'吗?请显示其他人可以编译和运行的* complete *应用程序。是的,这需要努力。 –

+0

[这是我的尝试](http://pastebin.com/8HeBCv4b)围绕你所展示的内容('grow_array'和'memory_manager')构建一个代码。它似乎工作正常。如果您需要帮助,请提供*完整*示例,就像我所做的那样。投票结束。 –

+0

亲爱的克罗维拉先生,感谢您抽出时间发表评论。我已经包含了有关复制内核的问题。我没有添加它,因为在另一个内核中出现越界错误,如果我工作在“静态”大小的内存上,它工作正常。这让我相信代码的内存管理部分可能存在一个明显的错误。 –

回答

1

用新的更大的指针代替指针的代码显然不是超出边界错误的原因,尽管它触发了它。在不相关的内核中找到错误并修复它。谢谢大家。