内存空间主表
此页面上的每个枚举序号、地址空间 ID、分配器符号和每代几何图形都是从
libtpu-0.0.40-cp314轮中的libtpu.so中精确字节解码的(构建libtpu_lts_20260413_b_RC00、BuildID md589edbbe81c5b328a958fe628a9f2207d— 明确的版本锚)。其他版本会有所不同。
摘要
本附录是每个 libtpu.so 地址的单一综合参考 — 片外 HBM 主存储、片上 TensorCore 层(VMEM、SMEM、CMEM、SFLAG、IMEM)、BarnaCore 子核层、SparseCore 定序器池、主机接口和主机 RAM 池,以及 —正交 — SparseCore 后端用于标记指针的 SparseCore LLVM 地址空间 ID 空间(AS0 加上 0xC9..0xE1 / 0x1F5/0x1F6 带)。它将每层内存深度页面和两个 ISA/目标枚举页面上的事实聚合并交叉检查到一个主表中,并根据二进制文件重新验证。
这里有三个不同的、单独编号的整数空间,此页面的中心工作是将它们分开,因为同一个单词(smem,sflag,hbm)出现在所有三个中具有不同的整数:
- LLO
xla::jellyfish::MemorySpace枚举 — 17 个值 (0..16),每个 TensorCore LLO 加载/存储上的操作数空间标签,由MemorySpaceToString@0x1d6ffae0读取进行解码off_21CE6B08[ms]。这就是分配器、DMA 发射器和捆绑打包器进行调度的内容。smem= 5,sflag= 6,sparse_core_sequencer_smem= 14。 - 连线
MemorySpaceProto字段编号 — 相同的 17 个空格,重新映射整数(hib/vmem/cmem不同); (反)序列化器必须在边界处重新映射。归 内存空间枚举.md 所有。 - SparseCore
mlir::sparse_core::MemorySpace枚举(22 个值,从 1 开始,值 8 间隙)及其 LLVM 地址空间 ID(AS0、AS201..225、AS501/502)。这里smem= MS 1 (AS0)。由 地址空间-ids.md 和 fat-pointers-as789.md 所有。
这三个不能通过算术进行转换——只有命名池对应,并且只能通过物理标识对应。此页面提供了以 LLO 枚举为键的主表,然后是 LLO 序数的重点部分、SparseCore AS 空间的部分(包括死 AS7/8/9 胖指针保留)以及对齐/几何规则的部分。一个深页标签仍然与二进制文件不一致(一个离一的定序器 SMEM 名称);它已在下面纠正。
这是一个纯粹的参考目录 - 没有可以重新实现的算法,只有可以准确再现的数据。每个事实表都带有一个置信度列。
| LLO 枚举 | xla::jellyfish::MemorySpace — 17 个值 0..16 |
| LLO 解码器 | MemorySpaceToString(MemorySpace) @ 0x1d6ffae0 → off_21CE6B08[ms](无边界检查) |
| LLO 颜色重新映射 | ColorToMemorySpace(color) @ 0x1d6ffb00 → byte_B5435CA[color]、color < 0xA (10) |
| 电线枚举 | xla.jellyfish.MemorySpaceProto 描述符 @ VA 0xbf8cc80(17 个值,重新映射) |
| SparseCore 枚举 | mlir::sparse_core::MemorySpace — 22 个值,从 1 开始,值 8 间隙 |
| SparseCore AS↔MS | AddressSpaceToMemorySpace @ 0x14b78800 / MemorySpaceToAddressSpace @ 0x14b78780 (工作台dword_AF36CE8,面罩0x3FFF7F) |
| 通用分配器 | tpu::BestFitAllocator(208-B实例,ctor 0x1e817500);每层一个,每层 Config |
| 编译时放置器 | ProgramMemoryAllocator::AllocateBytes(MemorySpace, …) @ 0x1c629e40 |
| 信心 | 已确认(字节锚定),除非单元格或标注另有说明 |
主内存空间表
这些行以 LLO MemorySpace 枚举(操作数空间标签,通过 TensorCore 编译器和运行时端到端流动的一个数字)为键。 AS-id 是“物理上对应的”SparseCore 池的 SparseCore LLVM 地址空间整数,其中存在一个 — 这两个枚举仅在 SparseCore/SC 序列器池中相遇,并且对于 SparseCore 后端从不命名的纯 TensorCore 层,AS-id 列为空。 Allocator/owner 命名拥有该层字节的管理器; Owning page 是记录它的深层页面。每代尺寸/几何文字位于 chip_parts.binarypb(引导填充)中,而不位于 .text 中; 公式和字段偏移量是准确的,此处未断言文字字节计数(请参阅 芯片零件-binarypb.md)。
| LLO# | 空间 | AS-id | 用途 | 每代尺寸/几何形状 | 分配者/所有者 | 所属页面 |
|---|---|---|---|---|---|---|
| 0 | <no memory space> | — | 未设置/无效哨兵(默认构造) | — | — | 内存空间枚举.md |
| 1 | hbm | 203 (0xCB) | 片外DRAM主存储:程序I/O、溢出、嵌入 | 数十GiB; Config{base=0, end=chip_parts HBM −reserved, align=1024 B DMA / 16 KiB compile, granule=chip_parts} | BestFitAllocator(运行时)/ProgramMemoryAllocator(编译) | hbm-allocator.md,hbm-dma-alignment.md |
| 2 | hib | — | 主机接口缓冲区: HBM↔ HIB DMA 引擎驱动的主机暂存层 | 芯片_零件 | HIB DMA引擎 | 内存空间枚举.md |
| 3 | vmem | 205 (0xCD) | 矢量存储器:MXU/VPU 操作数分级,MSA kAlternate 快速层 | ~16–64 MiB/TensorCore; align=VmemAlignmentBoundaryInBytes()、granule=VmemWordSizeBytes() (Target+0x50C);银行 JF8/PF16/VF32/GL32 | BestFitAllocator / MSA + ProgramMemoryAllocator | vmem-allocator.md |
| 4 | cmem | — | 常量内存:Pufferfish只读大部分操作数池(专用联发加载槽) | CmemSizeBytes() (Target+0x460);字=颗粒=CmemWordSizeBytes()(Target+0x510,~16 B PF);仅银行 PF=32 | BestFitAllocator / MSA (xla_tpu_cmem_*) | cmem-pool.md |
| 5 | smem | 0 (0x0) | 标量内存:SPU 溢出/参数存储、循环计数器、完成描述符 | SmemSizeBytes() (Target+0x470);字=SmemWordSizeBytes()=4 B (Target+0x508);银行 JF2/PF8/VF8/GL8 | BestFitAllocator / ProgramMemoryAllocator(操作码驱动,不是 MSA) | smem-标量-内存.md,smem-register-window.md |
| 6 | sflag | 204 (0xCC) | 同步标志寄存器文件:DMA 完成/屏障握手字、原子计数器/完成位 | 字粒S32; SflagWordSizeBytes()(Target+0x504),log2缓存Target+0x4c8; byte_off = 4·n | BestFitAllocator(大小)+固定数量空间分区 | sflag-protocol.md |
| 7 | imem | 214 (0xD6) † | 指令存储器:捆绑定序器读取 | 芯片_零件 | 定序器 | 内存空间枚举.md |
| 8 | barna_core_bmem | — | BarnaCore(嵌入引擎)批量暂存器 | 芯片_零件;仅限 PXC 系列 | BarnaCore | 内存空间枚举.md |
| 9 | barna_core_smem | — | BarnaCore 标量暂存器 | Target+0x47C尺寸,+0x480底座,+0x51C字 | BarnaCore(BarnaCoreSflagImmPtr,范围蹦床) | smem-标量-内存.md |
| 10 | barna_core_sflag | — | BarnaCore 同步标志层(与 TC SFLAG 不同) | Target+0x478 (BarnaCoreSflagSizeBytes) | BarnaCore | sflag-protocol.md |
| 11 | barna_core_imem | — | BarnaCore指令存储器 | 芯片_零件 | BarnaCore | 内存空间枚举.md |
| 12 | sparse_core_sequencer_sflag | 223 (0xDF) ‡ | SC 定序器同步标志组 | 芯片_零件; SC 音序器 | SparseCore 定序器 | sflag-protocol.md |
| 13 | host | — | 主机驻留缓冲区(传输源/接收器;MSA 卸载溢出目标) | 主机DRAM | PremappedMemoryManager / tsl::BFCAllocator 超过 posix_memalign | 概述.md |
| 14 | sparse_core_sequencer_smem | 224 (0xE0) ‡ | SC 定序器标量暂存器(众所周知的常数:chip_id、replica_id,...) | SCS SMEM 64 KiB VF/GL/GF 上的硬立即数 | SparseCore 定序器 | smem-标量-内存.md |
| 15 | sparse_core_private_stack_hbm | 203 (0xCB) | 每个 SC 私有堆栈由 HBM 雕刻而成 | HBM 支持 | HBM 支持 | 内存空间枚举.md |
| 16 | pinned_hbm | — | 用于主机可见 DMA 的页面固定 HBM(重新打包程序可能不会重新定位) | 1024 B DMA底板+主机引脚 | HBM(固定) | hbm-dma-alignment.md |
注意 — † AS-id 列将每个 TensorCore 层映射到物理上对应的SparseCore 池,而不是身份。
imem(LLO 7) ↔ SCtimem(AS 214) 和sparse_core_sequencer_sflag/_smem(LLO 12/14) ↔ SCsflag_scs/smem_scs(AS 223/224) 是物理身份对应,而不是算术转换。 ‡ SparseCore 定序器库是每个 SCS 的变体; AS-id 带还承载每块(AS217 sflag_tile、AS219 smem_tile)和芯片共享(AS202 spmem)SC 池,这些 SC 池具有无 LLOMemorySpace等效项(它们仅存在于 SparseCore LLVM 降低内)。请参阅下面的 SparseCore AS 部分。明白了 —
0x21ce6b08处的MemorySpaceToString表不会停在索引 16 处。索引 17/18/19 解析为absolute、heap_relative(0x8678cad),并且stack_relative(0x8678cbb) — 附加到同一字符串数组的指针相对性标签,不是内存池。它们属于LloAddress搬迁模型。按字符串表长度调整枚举大小或将absolute/heap_relative/stack_relative视为层的重新实现是错误的:规范区域枚举恰好是 17 个值。
LLO MemorySpace 枚举(TensorCore 操作数标签)
解码器和地面实况
MemorySpaceToString 是整数→区域映射的基本事实:它是没有边界检查的单索引负载,因此枚举值是直接数组索引,并且超长表与相对性标签共享。
// xla::jellyfish::MemorySpaceToString(MemorySpace ms) sub_1D6FFAE0, 14 bytes
const char *MemorySpaceToString(int ms):
return (&off_21CE6B08)[ms]; // off_21CE6B08[ms] — no bounds check
```text
序数分配通过四种独立方式重新验证,所有字节精确且相互一致:
| 探头 | 功能 | 它的引脚是什么 |
|-------|----------|--------------|
| 字符串表索引 | `MemorySpaceToString` @ `0x1d6ffae0` | `off_21CE6B08[ms]` 平查找 |
| DMA 渲染开关 | `MemorySpaceToDriverResource` @ `0x1d6223e0` | 输入序号:`1=hbm,2=hib,3=vmem,4=cmem,5=smem,6=sflag,7=imem,8..11=barna_core_*,12..16=sparse_core_*`(cmem + SC 上致命) |
| CMEM常数因子 | `LloAddress::MakeCmemConstant` @ `0x1d60ba20` | `LloAddress(MemorySpace=4, off)` → `cmem = 4` |
| SC-seq SMEM 因子 | `LloAddress::MakeSparseCoreSequencerSmemConstant` @ `0x1d60bc60` | `LloAddress(MemorySpace=14, off)` → `sparse_core_sequencer_smem = 14` |
`MemBanks(MemorySpace)` 独立覆盖确认中范围序数:`GhostliteTarget::MemBanks` (`0x1d4969c0`) 对于 `ms==3` 返回 `32`,对于 `ms==5` 返回 `8`,否则为 FATAL —即 `kVmem=3`、`kSmem=5`。 `PufferfishTarget::MemBanks` (`0x1d493900`) 将 `qword_B5305C8[ms-3] = {16,32,8}` 索引到 `ms ∈ {3,4,5}` — 即 vmem/cmem/smem = 银行 16/32/8。
### DMA 渲染编号是第三个不同的整数空间
`MemorySpaceToDriverResource` (`0x1d6223e0`) 将 LLO 枚举映射到标记到 DMA 描述符地址字中的硬件驱动程序资源 ID。它“不是”枚举值,它“捕获”`cmem` 和 SparseCore 空间:
```c
// xla::jellyfish::MemorySpaceToDriverResource(MemorySpace ms) sub_1D6223E0
function MemorySpaceToDriverResource(ms):
switch ms: // ms = the 17-value LLO MemorySpace enum
case 0 (<no space>): return 10
case 1 (hbm): return 2
case 2 (hib): return 3
case 3 (vmem): return 4
case 4 (cmem): FATAL("Unsupported memory space") // memory_space.cc:31 — not DMA-addressable here
case 5 (smem): return 6
case 6 (sflag): return 0
case 7 (imem): return 5
case 8 (barna_core_bmem): return 7
case 9 (barna_core_smem): return 9
case 10 (barna_core_sflag): return 1
case 11 (barna_core_imem): return 8
case 12..16 (sparse_core_*): FATAL("Unsupported memory space") // memory_space.cc:49sflag → render id 6 排序此开关意味着与 SflagImmPtr (0x1d5185a0) 烘焙到其指针中的值相同:它将渲染空间 6 传递到 ImmPtr,而结果操作数仍然带有 kSflag(6) 标记。重新实现者必须端到端携带 MemorySpace 枚举,并通过此显式开关在描述符边界仅转换为驱动程序资源 id。
线格式重映射
LLO 通过 MemorySpaceProto(描述符 @ VA 0xbf8cc80)进行序列化。原型和 C++ 枚举在 2..11 中使用 不同 整数命名相同的 17 个空格(hib 是 C++ 2 / 原型 10;vmem 是 C++ 3 / 原型 2;cmem 是 C++ 4 / 原型 11);他们同意 0、1 和 12..16。完整的重映射表和屏蔽的 DMA 有效性门位于 内存空间枚举.md 上;将原始字段编号与运行时枚举合并的(反)序列化器会默默地重新标记每个 vmem/cmem/hib 缓冲区。
规范分配,四种锚定方式
注意 — 字节精确序数分配是本页顶部的 17 值表,以上面的四种独立方式锚定(
MemorySpaceToString、MemorySpaceToDriverResource、MakeCmemConstant、MakeSparseCoreSequencerSmemConstant)。重新实现者最常出错的边界情况:sflag = 6(不是 7)与imem = 7;sparse_core_sequencer_sflag = 12、host = 13和sparse_core_sequencer_smem = 14(定序器 SFLAG/SMEM 序号不相邻 —host位于它们之间);hib = 2和pinned_hbm = 16(插槽2处没有kPinnedHbm)。 概述.md §2 具有相同的kNone=0 … kPinnedHbm=16分配。
SparseCore 地址空间
两个数字空间,通过构造不相交
SparseCore LLVM 后端用数字地址空间 ID 标记每个指针 - !llvm.ptr<N> 中的 N - 从稀疏的带状范围中提取:0(继承的标量内存)、201..225(0xC9..0xE1、 SC 特定池和 *Any 别名超集)和 501/502(0x1F5/0x1F6,两个 CBREG 循环缓冲区窗口)。每个 ID 1:1 映射到基于 1 的 mlir::sparse_core::MemorySpace 枚举值(22 个值,值 8 间隙)。转换是字节精确且自逆的:
// AddressSpaceToMemorySpace(uint id) sub_14B78800 (low 32 bits of 0x1_0000000N = MS)
// MemorySpaceToAddressSpace(MemorySpace ms) sub_14B78780
// guard: (ms-1) > 0x15 || ((0x3FFF7F >> (ms-1)) & 1) == 0 -> FATAL("Unsupported memory space")
// return dword_AF36CE8[ms-1]
```text
有效性掩码 `0x3FFF7F` 是 22 个有效 `MemorySpace` 值的位集,其中值 8 间隙清零; `ms-1 > 0x15` 界定表格。
### AS-ID主表
`MS#` 是基于 1 的 `mlir::sparse_core::MemorySpace`; `tile?` 是 `IsOffTileMemory == false`,仅适用于 MS 2 和 MS 18。空白 MS# 表示 ID 是别名分析分组或没有物理池的保留间隙。
| AS# | 六角形 | 池 (`stringifyMemorySpace`) | MS# | 瓷砖? | 注释 |
|----:|-----|-------------------------------|----:|:-----:|-------|
| 0 | `0x00` | `smem` | 1 | 关闭 | 继承基础TPU标量内存 |
| 201 | `0xC9` | `tile_spmem` | 2 | **ON** | 每块 SC SRAM (KB) |
| 202 | `0xCA` | `spmem` | 3 | 关闭 | 芯片共享SC SRAM (MB) |
| 203 | `0xCB` | `hbm` | 4 | 关闭 | 全局(GB)嵌入表 |
| 204 | `0xCC` | `sflag` | 5 | 关闭 | 同步标志存储器(MS 22 `sflag_tc` 也映射到此处) |
| 205 | `0xCD` | `vmem` | 6 | 关闭 | TC向量存储器(TC↔SC切换) |
| 206/207 | `0xCE`/`0xCF` | — | — | — | 预留间隙 |
| 208 | `0xD0` | `dreg` | 7 | 关闭 | 数据寄存器窗口 |
| 209/210 | `0xD1`/`0xD2` | — | — | — | 预留间隙 |
| 211 | `0xD3` | — (`SflagAny`) | — | 关闭 | sflag 可能别名超集(无池) |
| 212 | `0xD4` | `smem_any` | 9 | 关闭 | smem 可能别名超集 |
| 213 | `0xD5` | `hbm_any` | 10 | 关闭 | hbm 可能别名超集 |
| 214 | `0xD6` | `timem` | 11 | 关闭 | 每块指令存储器 |
| 215 | `0xD7` | `simem` | 12 | 关闭 | SC指令存储器(空`desc`) |
| 216 | `0xD8` | `iova` | 13 | 关闭 | I/O虚拟地址(GB) |
| 217 | `0xD9` | `sflag_tile` | 14 | 关闭 | 每块 sflag 银行 |
| 218 | `0xDA` | `spmem_any` | 15 | 关闭 | spmem 可能别名超集 |
| 219 | `0xDB` | `smem_tile` (`TileSmem`) | 16 | 关闭 | 每图块 SMEM (KB) |
| 220 | `0xDC` | `mar` | 17 | 关闭 | 内存访问区域(空 `desc`) |
| 221/222 | `0xDD`/`0xDE` | — | — | — | 预留间隙 |
| 223 | `0xDF` | `sflag_scs` | 20 | 关闭 | 每个 SCS 标志银行 |
| 224 | `0xE0` | `smem_scs` | 21 | 关闭 | 每个 SCS SMEM (KB) |
| 225 | `0xE1` | — (`SflagAnySynctile`) | — | 关闭 | sflag-any-synctile(无池) |
| 501 | `0x1F5` | `tile_spmem_cb` | 18 | **ON** | CBREG 窗口 TILE_SPMEM |
| 502 | `0x1F6` | `smem_cb` | 19 | 关闭 | CBREG 加窗 SMEM |
> **注意 —** 平铺门是单个掩码比较:`IsOffTileMemory(ms) = (ms & ~0x10) != 2` (`0x13d7ac00`)。清除位 4 将 MS 2 (`tile_spmem`) 和 MS 18 = `0x12` (`tile_spmem_cb`) 折叠在一起,因此**只有**这两个在图块上;每个其他池都需要 DMA/流/同步才能到达。这是 DMA 和流降低在选择数据移动内在函数之前参考的谓词,这也是 TEC 需要进行图块 ID 转换以将图块上 `TileSpmem`(201) 指针转换为图块外可寻址 `Spmem`(202) 指针的原因。
### `*Any` 可能别名规范化
四个 ID(`211 SflagAny`、`212 SmemAny`、`213 HBMAny`、`218 SpmemAny` 以及合成的 `225 SflagAnySynctile`)带有描述,但**没有** `MemorySpace` 池 — 它们是别名分析分组,后端将指针扩大到当其确切的瓦片或核心静态未知时。 `GetAnyTypeFromAddressSpace(int)` (`0x1357b400`) 将具体 ID 规范化为其通配符;在叶子或已经通配符的空间 `LOG(FATAL)` 上调用它,因此它仅在以下具体空间上是总计:
| 混凝土ID(池) | → 规范 ID(超集) |
|---|---|
| 201 `tile_spmem`, 202 `spmem` | 218 `SpmemAny` |
| 203 `hbm` | 213 `HBMAny` |
| 204 `sflag` | 211 `SflagAny` |
| 205 `vmem` | 205 `vmem`(自身 — 无单独的通配符) |
| 219 `smem_tile`, 0 `smem` | 212 `SmemAny` |
这是 SparseCore 对胖指针问题的答案:指向 HBM/SPMEM 的指针(其拥有的图块是运行时值)无法证明与另一个不相交,因此后端分配 `*Any` 超集,并让别名分析将它们视为可能别名。具体与 `Any` 的区别是静态解析的图块本地访问不会被悲观的原因。
### AS7/8/9 胖指针保留已死
TPU `DataLayout` (@ `0x973de15`) 带有 `p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32 … ni:7:8:9` 片段 — 160/128/192 位 AMDGPU **buffer-fat-pointer** 系列 — 逐字继承,因为 TPU `TargetMachine` 共享 LLVM 的 AMDGPU ABI 片段。 **没有任何 TPU 或 SparseCore 操作会构造 AS7/8/9 指针。** SparseCore 指针最多是一个 64 位 LLVM ptr(默认 `p:64:64`),带有 32 位字偏移量;路由胖指针将打包成位作为单独的 SSA 操作数(`tpu_tileid` 用于 on-tile TEC 转换,destination-id 用于远程)。全部负结果、操作数拆分和保值 `addrspacecast` 降低均归 [fat-pointers-as789.md](../sparsecore/fat-pointers-as789.md) 所有。
> **明白了 —** 不**从 `{7,8,9}` 分配 SparseCore 地址空间编号。从`{0, 201..225, 501, 502}`分配。这两个范围是不相交的,并且驱动 `p7/p8/p9` `DataLayout` 条目的重新实现将查找不存在的构造函数。
---
## 对齐、几何和分配器模型
### 一个分配器类,每层配置
每个运行时层(HBM、VMEM、CMEM、SMEM、SFLAG)都是单个 `tpu::BestFitAllocator` 实例(208 B,ctor `0x1e817500`),仅通过 32 字节 `MemoryAllocator::Config{base_offset, allocatable_range_end, alignment, granule}` 进行区分。分配器内没有 `HbmAllocator`/`VmemAllocator`/`SmemAllocator` 类,也没有每个 `TpuVersion` 分支:每个每个代码名分歧都是 `chip_parts.binarypb` 中携带的 *data* 并显示为 `Config` 三元组。分配/解除分配算法(边界标签 SwissTable + 按大小排序的自由 RB 树、最佳拟合 `lower_bound`、渴望双向合并、无最小分割余数)在 [hbm-allocator.md](../memory/hbm-allocator.md) 上记录一次。
### 每层对齐/几何
| 等级 | `base_offset` | `alignment` | `granule` | 几何源 |
|------|---------------|-------------|-----------|-----------------|
| HBM | 0 | **1024 B** DMA 楼层 (`kHbmMinimumDmaAlignment`); **16 KiB** 编译时 (`xla_jf_program_hbm_alignment_in_kib`) | 芯片_零件HBM颗粒 | 双量子;有问题的 DMA 下限强制执行 (`WritePremappedHbm`) + 描述符 (`SetHbmAddress`,致命) |
| VMEM | 0 | `VmemAlignmentBoundaryInBytes()` — `ChunkBytes` (JF) / `max(GranuleBytes, VmemWordSizeBytes)` (PF/VF/GL) | `VmemWordSizeBytes()` (`Target+0x50C`) | `ChunkBytes = 4·topology.word_count` (`0x1d619f40`) |
| CMEM | 0 | `CmemWordSizeBytes()`(`Target+0x510`,~16 B PF) | `CmemWordSizeBytes()` | 对齐==颗粒;仅限河豚 |
| SMEM | 0 | `SmemWordSizeBytes()`(4 B;`Target+0x508`) | `SmemWordSizeBytes()` | 字平; `SmemWordImmPtr` 断言字 == 4 B |
| SFLAG | 0 | `SflagWordSizeBytes()` (`Target+0x504`) | `SflagWordSizeBytes()` | `byte_off = 4·n` 每个标志; log2 缓存 `Target+0x4c8` |
| 主机(预映射) | 每个分区 `partition_size·i` | 4 KiB 如果 ≤ 2 MiB,否则 2 MiB (`PickPageAlignment`) | = 对齐 | `PremappedMemoryManager` 超过 `posix_memalign` |
| 主机(BFC卸载) | 0 | ≥ 16 B (`posix_memalign`) | 2 MiB 区域增长 | `tsl::BFCAllocator`(256 GiB 上限) |
> **明白了 —** HBM 有 **两个** 对齐编号,混淆它们会默默地损坏 DMA。 `kHbmMinimumDmaAlignment = 1024 B` 是“硬件”底层:每个 DMA 站点都用 `& 0x3FF` 进行掩码,并拒绝非零余数(有问题时可恢复 `RetCheck`,描述符处致命 `CHECK`)。 16 KiB 编译时数字*在 MSA 放置它之前将每个程序级 HBM 张量向上舍入。 1024-B层为电线合约; 16-KiB 规则是放置合约。请参阅 [hbm-dma-alignment.md](../memory/hbm-dma-alignment.md)。
>
> **注意 —** 片上层 (VMEM/CMEM/SMEM/SFLAG) 全部设置 `alignment == granule == <tier>WordSizeBytes()` 和 `base_offset == 0`。只有 HBM 将对齐与颗粒分开,并且只有主机预映射管理器使用非零 `base_offset`。每个代号的数字字/字节大小存在于 `chip_parts.binarypb` 中,而 **不在** `.text` 中;上面的*公式*和字段偏移量是精确的,文字未断言。用于缓冲 pad 的 `(sublane, lane)` 片上图块几何结构 — Trillium/v5+ 上的 `(8, 128)`、v4 上的 `(16, 128)` — 由 [tpu-buffer-layout.md](../memory/tpu-buffer-layout.md) 所有。
### 每代片上存储体数量
*烘焙到 `.text`(不是 `chip_parts`)中的一片片上几何图形是存储体计数,由每个 `Target` `MemBanks(MemorySpace)` 虚拟返回。字节偏移 `B` 的存储体索引是 `(B / <tier>WordSizeBytes) mod MemBanks(tier)`。存储是一个访问调度属性,而不是一个分配属性——分配器分发字节偏移量,LLO 捆绑包打包器在发布时导出 `(bank, sub-bank)` 坐标。反编译确认:
| 目标(生成) | VMEM (MS 3) | CMEM (MS 4) | SMEM (MS 5) | `MemBanks` 配件 |
|---|---:|---:|---:|---|
| JellyfishTarget (v2) | 8 | — (`LogFatal`) | 2 | `0x1d48fc80` |
| 河豚目标 (v4) | 16 | **32** | 8 | `0x1d493900` (`qword_B5305C8[ms-3]={16,32,8}`) |
| ViperfishTarget (v5p) | 32 | — (`LogFatal`) | 8 | `0x1d4999c0` |
| GhostliteTarget (v6e) | 32 | — (`LogFatal`) | 8 | `0x1d4969c0` |
Pufferfish 是唯一 `MemBanks(kCmem)` 返回值而不是 `LogFatal` 的一代 — CMEM 是仅在 Pufferfish(PXC、TPU v4)上的真正层的结构标记。 Viperfish (`0x1d4999c0`) 评级为 HIGH(符号表主体,来源与已确认的 Ghostlite 形状相同,不单独重新读取)。
### MSA 管理仅限 VMEM/CMEM
只有 VMEM(以及河豚上的 CMEM)由 MSA 管理 — `kAlternate`/`kDefault` 拉锯战为 `HloValue` 着色。 SMEM由标量加载/存储**操作码语义**放置(操作数声明`MemorySpace=kSmem`); SFLAG 放置在固定的**数字空间分区**中,而不是字节堆中。尽管如此,所有层仍然流经相同的 `ProgramMemoryAllocator` → `ProgramMemoryMetadata_Allocation` 原型 → `CreateFromProto` → `BestFitAllocator` 交接。通过 MSA 成本模型路由 SMEM/SFLAG 的重新实现者将会放错它们的位置。
### 缓冲区布局定序器-SMEM标签
> **注意 —** `ShapeSizeBytesRaw` (`0x1d6add40`) 密集分支测试 `ColorToMemorySpace(layout.memory_space) == 12`。规范 LLO 枚举中的常量 `12` 是 `sparse_core_sequencer_sflag`,**不是** `sparse_core_sequencer_smem`(即 `14`,由 `MakeSparseCoreSequencerSmemConstant` @ `0x1d60bc60` 进行字节确认)——两者是一对一的邻居,很容易贴错标签。该分支将 `sparse_core_sequencer_sflag` 颜色的缓冲区路由到密集的、直到字节大小的路径。 `ColorToMemorySpace` (`0x1d6ffb00`) 是 `byte_B5435CA[color]` 与 `color < 0xA` 的重映射,因此其*输出*是规范的 `MemorySpace` 枚举 — `12` 是一个枚举值,而不是原始布局颜色。
---
## 交叉引用
- [内存空间枚举.md](../isa/memory-space-enum.md) — 17 值 LLO `MemorySpace` 枚举、`MemorySpaceToString` 解码器、proto↔枚举重映射和屏蔽 DMA 有效性门;本页序数词的权威
- [概述.md](../memory/overview.md) — 六区域分类、通用 `BestFitAllocator` 以及编译时→运行时切换;它的 §2 带有与此处使用的相同的规范 `kNone=0 … kPinnedHbm=16` 序数分配
- [hbm-allocator.md](../memory/hbm-allocator.md) — 每层共享的通用最佳分配/解除分配算法
- [hbm-dma-alignment.md](../memory/hbm-dma-alignment.md) — 1024-B DMA 底层与 16-KiB 编译时程序对齐
- [vmem-allocator.md](../memory/vmem-allocator.md) — `kAlternate` 快速层;每代 VMEM 大小/字/库/对齐公式
- [cmem-pool.md](../memory/cmem-pool.md) — 仅河豚常量内存操作数池; `MemBanks(kCmem)=32`,`xla_tpu_cmem_*` 系列
- [smem-标量-内存.md](../memory/smem-scalar-memory.md) — SPU 标量层 (`kSmem`=5); `SmemWordImmPtr`,操作码驱动的布局,BarnaCore SMEM 兄弟
- [smem-register-window.md](../memory/smem-register-window.md) — 为什么不存在 SMEM 寄存器窗口;平面 32 条目 SREG 文件和 CBREG/OperandWindow 消歧
- [sflag-protocol.md](../memory/sflag-protocol.md) — 同步标志原子层 (`kSflag`=6); `4·n` 步幅、计数器/完成位语义、`Vsync*`/`Vwait*` 原语
- [tpu-buffer-layout.md](../memory/tpu-buffer-layout.md) — 逻辑 XLA 缓冲区如何映射到这些层中的填充、平铺物理偏移(其 §4 序列器-SMEM `12` 标签是 `sparse_core_sequencer_sflag` 枚举值,而不是 SMEM — 请参阅上面的注释)
- [地址空间-ids.md](../targets/address-space-ids.md) — 完整的 SparseCore AS-ID 表、`*Any` 可能别名规范化和 `CheckAddressSpaces`
- [fat-pointers-as789.md](../sparsecore/fat-pointers-as789.md) — 死 AS7/8/9 胖指针保留和实际 64 位/32 位字 SparseCore 指针表示
- [芯片零件-binarypb.md](../targets/chip-parts-binarypb.md) — 提供 `.text` 中缺少的每个代号大小/单词/颗粒文字的启动时资源
- [每代比较矩阵.md](per-gen-comparison-matrix.md) — 此表提供的每代特征/几何形状比较
- [返回索引](../index.md) — 第十七部分 — 附录