CUDA内核内存读写不平衡问题技术咨询
CUDA内核内存读写量不平衡问题分析
针对你提供的CUDA内核和ncu统计结果,以下是具体原因拆解:
核心数据基准
先明确逻辑读写的理论值:
- 总线程数:
8192块 × 256线程/块 = 2097152线程 - 每个线程处理:16次写入 + 16次读取,对应
16×4=64字节/线程 - 逻辑读写总量:
2097152 × 64 = 134217728字节 = 128MB
读取量305MB的原因
你的读取操作是连续合并访问:每个线程读取offset+16到offset+31的16个连续int,整体覆盖内存的后半段128MB区域。这种模式下硬件会以最优事务(如128字节事务)批量读取,但额外的读取量来自:
- 写入操作采用写回缓存策略:写入前半段内存时,需要先从DRAM加载完整的128字节缓存行到L1,这部分加载流量会被统计到读取量中。
- 缓存命中优化:
cudaMemset已将全量内存写入过,部分缓存行仍保留在L2/L1中,因此实际从DRAM读取的缓存行数量少于理论值,最终读取量介于128MB(纯逻辑读取)和384MB(逻辑读取+全量缓存行加载)之间,与ncu显示的305MB吻合。
写入量1.07GB的原因
写入操作是非合并访问:每个线程写入offset到offset+15的16个连续int,但线程间的写入块间隔16个int(64字节),导致硬件无法合并事务,额外开销来自:
- 非合并事务拆分:这种分散的访问模式会让硬件为每个线程的写入块生成独立事务(如安培架构下,每个64字节非合并块触发2个128字节事务)。
- 写回缓存的完整行写入:修改缓存行前半段后,缓存行被替换时会以完整128字节写回DRAM,而非仅修改的64字节。
两者叠加后,实际DRAM写入量被放大至逻辑量的8倍左右,对应ncu显示的1.07GB。
验证建议
- 调整写入地址为连续模式:将内核中的赋值语句改为
ptr[offset+i+16] = ptr[offset+i],此时写入地址为连续的后半段内存,属于合并访问,写入量会接近128MB。 - 查看ncu事务指标:通过
ncu --metrics gld_transactions,gst_transactions,transaction_size统计事务数和单事务大小,计算总字节数可验证与读写量的对应关系。
内容的提问来源于stack exchange,提问作者Alex Chen
相关产品推荐
相关产品推荐

