【infra之路】Shared Memory 的访问范围:严格限定于单个 SM

Shared Memory 是 SM 私有的,只有分配到该 SM 上的 Block 才能访问。 其他 SM 上的线程无法直接读写任何非本 SM 的 Shared Memory。


核心规则

问题 答案
同一 SM 内的多个 Block 能否共享 SMEM? 不能。每个 Block 有独立的 SMEM 分配,互不可见
不同 SM 上的线程能否访问同一块 SMEM? 绝对不能。SMEM 没有全局地址空间
SMEM 的生命周期 从 Block 调度到 SM 开始,到 Block 执行结束为止
SMEM 的物理位置 嵌入在 SM 内部,与 L1 Cache 共用 SRAM,片外不可达

为什么这样设计?

复制代码
┌─────────────────────────────────────────────────────┐
│                    GPU Die                          │
│                                                     │
│  ┌──────────┐  ┌──────────┐       ┌──────────┐    │
│  │   SM 0   │  │   SM 1   │ ...   │   SM N   │    │
│  │ ┌──────┐ │  │ ┌──────┐ │       │ ┌──────┐ │    │
│  │ │ SMEM │ │  │ │ SMEM │ │       │ │ SMEM │ │    │
│  │ │(私有)│ │  │ │(私有)│ │       │ │(私有)│ │    │
│  │ └──────┘ │  │ └──────┘ │       │ └──────┘ │    │
│  └──────────┘  └──────────┘       └──────────┘    │
│        ↕              ↕                  ↕         │
│  ┌─────────────────────────────────────────────┐   │
│  │           L2 Cache (全芯片共享)              │   │
│  └─────────────────────────────────────────────┘   │
│                       ↕                            │
│  ┌─────────────────────────────────────────────┐   │
│  │              HBM / GDDR (全局)               │   │
│  └─────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────┘
  • 带宽 :SMEM 提供 ~20TB/s 级带宽,靠的是每个 SM 独立一份。如果全局共享,带宽会坍缩到 HBM 级别(~3TB/s)
  • 延迟:SMEM 延迟 ~30 cycles,因为物理距离在 SM 内部。跨 SM 访问不可能保持这个延迟
  • 同步__syncthreads() 只同步同一 Block 内的线程,正是因为 SMEM 的作用域就是 Block

如果需要跨 SM 通信怎么办?

必须通过更高层级的存储中转:

需求 机制 延迟代价
同 Grid 内 Block 间通信 Global Memory + __threadfence_system() / Cooperative Groups ~400+ cycles
同 Kernel 内流水线阶段 Persistent Thread + Global Memory 信号量 ~400+ cycles
跨 Kernel 数据传递 Global Memory / Managed Memory Kernel launch overhead
同 SM 内 Warp 间通信 Shared Memory ✅(同一 Block 内) ~30 cycles

⚠️ 注意 :即使是同一个 Grid 中的两个 Block 被调度到同一个 SM 上,它们的 SMEM 仍然是隔离的。SM 会为每个活跃 Block 分配独立的 SMEM 区域,彼此不可见。


常见误解澄清

误解 事实
"同一 SM 上的 Block 可以共享 SMEM" ❌ 每个 Block 有独立 SMEM 分区,硬件强制隔离
"SMEM 可以通过指针传给其他 SM" ❌ SMEM 地址是 SM 局部虚拟地址,跨 SM 无意义
"__shared__ 变量在所有 SM 上是同一份" ❌ 每个 SM 上每个 Block 都有自己的一份副本
"Hopper 的 TMA 让 SMEM 变全局了" ❌ TMA 只是异步拷贝引擎,目标仍是本 SM 的 SMEM

一句话总结

Shared Memory 是 SM 级别的私有资源,作用域严格等于一个 Block。它的高带宽和低延迟正是以"不可跨 SM 访问"为代价换来的。任何跨 SM 的数据交换都必须上升到 Global Memory 或更高层级------这是 GPU 存储层次中不可逾越的物理边界。

相关推荐
wuminyu2 小时前
Kafka中sendfile与mmap实现机制解析
java·linux·c语言·jvm·c++
新时代牛马2 小时前
嵌入式网络完整篇:从LwIP/以太网驱动到 Linux netdev 与排障
linux·网络·php
前端世界3 小时前
Linux服务器实战:NTP时间同步、SELinux权限与rsyslog日志管理,一次搞懂三大运维问题
linux·运维·服务器
Android系统攻城狮3 小时前
Linux Gstreamer深度解析之gst_audio_converter_new调用流程与实战(二十)
linux·运维·服务器·gstreamer音视频·音视频进阶
海宇服务3 小时前
零信任架构实战:基于海宇对外投资历史查询服务构建自动化供应商准入网关
运维·人工智能·架构·自动化
考虑考虑3 小时前
Java实现hmacsha256加密算法
java·后端·java ee
上海云盾-小余3 小时前
BGP 高防底层原理:TCP 异常流量识别与清洗机制
运维·网络·tcp/ip
captain3763 小时前
▲网络原理(2)-TCP
java·服务器·网络·tcp/ip·java-ee
MetaLite3 小时前
SpringBoot接口分层规范-外网网关内部服务与参数边界
java·数据库·spring boot
Co_Hui4 小时前
Java 线程状态
java