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

增大网格尺寸时CUDA kernel返回错误计算结果的问题咨询

问题根因

你遇到的异常是myadd内核存在线程竞态条件导致的:

  • 原内核中同一线程块内的所有线程都会执行sum[blockIdx.x] = 0写入操作,该操作和后续的atomicAdd_block累加操作没有任何同步约束。
  • 当同块内部分线程已经完成原子累加后,还未执行赋值操作的线程一旦运行到sum[blockIdx.x] = 0,会直接将已累加的结果清零,最终求和结果就会小于正确值。
  • 网格尺寸较小时,SM资源充足,线程块能被连贯调度,大概率所有线程先完成赋值再执行累加,竞态触发概率极低;当网格尺寸提升到65535时,SM上的线程上下文切换变得频繁,同块线程的执行时序差变大,竞态极易触发。

修复方案

修改myadd内核,仅让块内的0号线程完成对应sum元素的初始化,初始化完成后增加块内同步,保证所有线程累加前看到的是初始化后的0值:

__global__ void myadd(const int *in, int *sum) {
    // 仅块内0号线程执行初始化操作
    if (threadIdx.x == 0) {
        sum[blockIdx.x] = 0;
    }
    // 块内同步,确保所有线程感知到初始化完成
    __syncthreads();
    atomicAdd_block(&sum[blockIdx.x], in[threadIdx.x]);
}

修改后重新编译运行即可解决大网格下的结果错误问题。

内容的提问来源于stack exchange,提问作者user2348209

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 23:15:03