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')構建一個代碼。它似乎工作正常。如果您需要幫助,請提供*完整*示例,就像我所做的那樣。投票結束。 –
親愛的克羅維拉先生,感謝您抽出時間發表評論。我已經包含了有關複製內核的問題。我沒有添加它,因爲在另一個內核中出現越界錯誤,如果我工作在「靜態」大小的內存上,它工作正常。這讓我相信代碼的內存管理部分可能存在一個明顯的錯誤。 –