You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CUDA设备端int标记变量拷贝回主机未更新问题求助

核心错误原因

  1. 内核中对finish指针的赋值逻辑错误:你编写的finish = (int*) threadIdx.x;是直接修改finish指针本身的地址值,将其指向了地址为5的非法设备内存,完全没有修改你通过cudaMalloc申请的目标设备内存的内容。GPU侧打印的*finish = 5是非法地址访问的巧合结果,和你要操作的threadBingo对应的内存没有任何关系,所以主机侧拷贝回来的值还是初始的0。
  2. 存在类型不匹配的逻辑错误:__shared__ int shared是整型变量,拿它和指针类型的NULL做比较属于不符合语义的写法,即使运行没报错也存在逻辑隐患。
  3. 同步逻辑存在风险:线程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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 15:06:00