当前位置: 首页 > news >正文

CUDA-内存访问模式

在 GPU 计算中,内存访问模式 直接影响程序的性能,尤其是 全局内存(global memory) 访问的合并性(coalescing)局部性(locality)


1. GPU 内存层次结构

GPU 具有多级存储,每一级的访问速度不同:

  • 寄存器(Register):每个线程私有,访问最快。
  • 共享内存(Shared Memory):线程块(Block)内共享,比全局内存快很多。
  • L1/L2 缓存(Cache):缓存局部数据,减少全局内存访问。
  • 全局内存(Global Memory):最慢,但存储量最大,需要优化访问模式。

2. 主要内存访问模式

(1) 合并访问(Coalesced Access)

线程按顺序访问连续的内存地址

  • 每个 warp(32 个线程)共同访问一段连续的全局内存
  • 减少内存事务(memory transactions),提高带宽利用率。

示例(合并访问)

__global__ void coalesced_access(float *A, float *B, int N) {
    int tid = threadIdx.x + blockIdx.x * blockDim.x;
    if (tid < N)
        B[tid] = A[tid];  // 线程按顺序访问连续地址
}

📌 优化要点

  • 按行加载(Row-major order) 比按列加载更好。
  • 让线程 ID 与数据索引匹配

(2) 非合并访问(Non-Coalesced Access)

🚨 线程访问不连续的内存地址

  • 每个线程访问的地址分散在不同的内存块,导致多个内存事务,降低效率。

示例(非合并访问)

__global__ void non_coalesced_access(float *A, float *B, int N, int stride) {
    int tid = threadIdx.x + blockIdx.x * blockDim.x;
    if (tid * stride < N)
        B[tid] = A[tid * stride];  // 线程访问间隔 stride
}

🚩 问题

  • 内存事务数增加,吞吐量降低
  • 不建议使用 stride 访问全局内存

(3) 行主序(Row-Major) vs. 列主序(Column-Major) 访问

  • 行主序存储(Row-major order):C 语言默认方式,数据按行优先存储。
  • 列主序存储(Column-major order):Fortran、MATLAB 采用,数据按列优先存储。

📌 访问模式建议

  • 矩阵遍历时,按存储方式优化访问方式避免列访问全局内存,可用共享内存优化。

示例(行访问更快)

// 行访问(合并访问)
for (int row = 0; row < N; row++)
    for (int col = 0; col < N; col++)
        B[row * N + col] = A[row * N + col];

// 列访问(非合并访问,性能低)
for (int col = 0; col < N; col++)
    for (int row = 0; row < N; row++)
        B[row * N + col] = A[col * N + row];  // 非合并访问

(4) 共享内存优化

使用 共享内存(shared memory) 解决非合并访问问题:

__global__ void shared_memory_access(float *A, float *B, int N) {
    __shared__ float tile[32][32];  // 共享内存 tile
    int row = threadIdx.y + blockIdx.y * blockDim.y;
    int col = threadIdx.x + blockIdx.x * blockDim.x;

    if (row < N && col < N) {
        tile[threadIdx.y][threadIdx.x] = A[row * N + col];  // 先加载到共享内存
        __syncthreads();
        B[col * N + row] = tile[threadIdx.y][threadIdx.x];  // 从共享内存存回
    }
}

共享内存缓存局部数据,提高访问效率


3. 访问模式优化策略

合并访问:线程访问连续地址,提高全局内存带宽利用率。
共享内存:减少不规则访问,提高数据重用。
优化存储顺序按行遍历按列遍历 快。
减少 stride 访问:避免跨步访问全局内存。
使用 L1 缓存(L1 cache)启用 L1 缓存优化非合并访问


4. 结论

访问模式内存层级访问效率典型应用
合并访问全局内存✅ 高效标量运算,向量计算
非合并访问全局内存❌ 低效矩阵按列访问
共享内存共享内存✅ 高效矩阵转置、卷积计算
寄存器寄存器✅ 最高线程局部变量

🚀 总结

  • 合并访问减少内存事务
  • 共享内存避免非合并访问
  • 行主序存储按行访问更快
  • 减少 stride 访问优化全局内存吞吐量

🔹 优化内存访问是 GPU 编程中提升性能的关键! 🚀

相关文章:

  • Spring Boot (maven)分页3.0版本 通用版
  • JAVA泛型介绍与举例
  • hashcat使用方法记录
  • SpringCould+vue3项目的后台用户管理的CURD【Taurus教育平台】
  • Linux---系统函数
  • 公牛充电桩协议对接单车汽车平台交互协议外发版
  • docker 进阶命令(基于Ubuntu)
  • 【吾爱出品】针对红警之类老游戏适用WIN10和11的补丁cnc-ddraw7.1汉化版
  • 基于单片机的开关电源设计(论文+源码)
  • 【spring cloud 3.0微服务部署】第三章:Nacos、LoadBalancer、GateWay、Ribbon集成之网关Gateway部署
  • Dubbo和OpenFeign的对比
  • 信息安全之网络安全
  • IoTDB 常见问题 QA 第五期
  • DeepSeek 助力 Vue 开发:打造丝滑的面包屑导航(Breadcrumbs)
  • 多行文本溢出裁剪(兼容版)
  • ABP - 事件总线之分布式事件总线
  • Cookie,Session ,token , JWT的区别
  • c++--define和const
  • 日志2025.2.15
  • B. Olya and Game with Arrays
  • 上海市税务局:收到对刘某某存在涉税问题的举报,正依法依规办理
  • 第一集|好饭不怕晚,折腰若如初见
  • 上海制造佳品汇大阪站即将启幕,泡泡玛特领潮出海
  • 特朗普中东行:“能源换科技”背后的权力博弈|907编辑部
  • 著名词作家陈哲逝世,代表作《让世界充满爱》《同一首歌》等
  • “降息潮”延续,多家民营银行下调存款利率