CUDA设备端int标记变量拷贝回主机未更新问题求助
核心错误原因
- 内核中对
finish指针的赋值逻辑错误:你编写的finish = (int*) threadIdx.x;是直接修改finish指针本身的地址值,将其指向了地址为5的非法设备内存,完全没有修改你通过cudaMalloc申请的目标设备内存的内容。GPU侧打印的*finish = 5是非法地址访问的巧合结果,和你要操作的threadBingo对应的内存没有任何关系,所以主机侧拷贝回来的值还是初始的0。 - 存在类型不匹配的逻辑错误:
__shared__ int shared是整型变量,拿它和指针类型的NULL做比较属于不符合语义的写法,即使运行没报错也存在逻辑隐患。 - 同步逻辑存在风险:线程5提前
return,没有执行到__syncthreads(),在部分CUDA架构下会导致线程块死锁。
修复方案
修正后的完整代码
__global__ void bingo(int * finish){ // 不要用shared当变量名,避免和__shared__关键字混淆 __shared__ int shared_flag; if(threadIdx.x == 5){ printf("\nassign to finish %d",threadIdx.x); shared_flag = threadIdx.x; // 解引用指针,给指针指向的内存空间赋值 *finish = threadIdx.x; printf("GPU says: %d\n",*finish); } // 保证所有线程都走到同步点,避免死锁 __syncthreads(); if(shared_flag != 0){ printf("\nreturn from thread: %d", threadIdx.x); return; } } int main() { int* threadBingo; cudaMalloc((void**)&threadBingo, sizeof(int)); // 初始化申请的设备内存,避免脏值 cudaMemset(threadBingo, 0, sizeof(int)); bingo<<<1,10>>>(threadBingo); cudaDeviceSynchronize(); // 直接用栈变量即可,不需要动态分配 int threadWhoMadeBingo; cudaMemcpy(&threadWhoMadeBingo, threadBingo, sizeof(int), cudaMemcpyDeviceToHost); printf("\n thread who made bingo %d\n", threadWhoMadeBingo); // 释放申请的设备内存 cudaFree(threadBingo); cudaDeviceReset(); return 0; }
额外说明
你之前用char *能正常运行大概率是写法巧合,当时应该是正确写了*finish = xxx的解引用赋值逻辑,而非修改指针本身。
内容的提问来源于stack exchange,提问作者addUsername
相关产品推荐
相关产品推荐

