Skip to content

内存空间主表

此页面上的每个枚举序号、地址空间 ID、分配器符号和每代几何图形都是从 libtpu-0.0.40-cp314 轮中的 libtpu.so 中精确字节解码的(构建 libtpu_lts_20260413_b_RC00、BuildID md5 89edbbe81c5b328a958fe628a9f2207d — 明确的版本锚)。其他版本会有所不同。

摘要

本附录是每个 libtpu.so 地址的单一综合参考 — 片外 HBM 主存储、片上 TensorCore 层(VMEM、SMEM、CMEM、SFLAG、IMEM)、BarnaCore 子核层、SparseCore 定序器池、主机接口和主机 RAM 池,以及 —正交 — SparseCore 后端用于标记指针的 SparseCore LLVM 地址空间 ID 空间(AS0 加上 0xC9..0xE1 / 0x1F5/0x1F6 带)。它将每层内存深度页面和两个 ISA/目标枚举页面上的事实聚合并交叉检查到一个主表中,并根据二进制文件重新验证。

这里有三个不同的、单独编号的整数空间,此页面的中心工作是将它们分开,因为同一个单词(smemsflaghbm)出现在所有三个中具有不同的整数:

  1. LLO xla::jellyfish::MemorySpace 枚举 — 17 个值 (0..16),每个 TensorCore LLO 加载/存储上的操作数空间标签,由 MemorySpaceToString @ 0x1d6ffae0 读取进行解码off_21CE6B08[ms]。这就是分配器、DMA 发射器和捆绑打包器进行调度的内容。 smem = 5sflag = 6sparse_core_sequencer_smem = 14
  2. 连线 MemorySpaceProto 字段编号 — 相同的 17 个空格,重新映射整数(hib/vmem/cmem 不同); (反)序列化器必须在边界处重新映射。归 内存空间枚举.md 所有。
  3. SparseCore mlir::sparse_core::MemorySpace 枚举(22 个值,从 1 开始,值 8 间隙)及其 LLVM 地址空间 ID(AS0AS201..225AS501/502)。这里 smem = MS 1 (AS 0)。由 地址空间-ids.mdfat-pointers-as789.md 所有。

这三个不能通过算术进行转换——只有命名池对应,并且只能通过物理标识对应。此页面提供了以 LLO 枚举为键的主表,然后是 LLO 序数的重点部分、SparseCore AS 空间的部分(包括死 AS7/8/9 胖指针保留)以及对齐/几何规则的部分。一个深页标签仍然与二进制文件不一致(一个离一的定序器 SMEM 名称);它已在下面纠正。

这是一个纯粹的参考目录 - 没有可以重新实现的算法,只有可以准确再现的数据。每个事实表都带有一个置信度列。

LLO 枚举xla::jellyfish::MemorySpace — 17 个值 0..16
LLO 解码器MemorySpaceToString(MemorySpace) @ 0x1d6ffae0off_21CE6B08[ms](无边界检查)
LLO 颜色重新映射ColorToMemorySpace(color) @ 0x1d6ffb00byte_B5435CA[color]color < 0xA (10)
电线枚举xla.jellyfish.MemorySpaceProto 描述符 @ VA 0xbf8cc80(17 个值,重新映射)
SparseCore 枚举mlir::sparse_core::MemorySpace — 22 个值,从 1 开始,值 8 间隙
SparseCore AS↔MSAddressSpaceToMemorySpace @ 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
1hbm203 (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.mdhbm-dma-alignment.md
2hib主机接口缓冲区: HBM↔ HIB DMA 引擎驱动的主机暂存层芯片_零件HIB DMA引擎内存空间枚举.md
3vmem205 (0xCD)矢量存储器:MXU/VPU 操作数分级,MSA kAlternate 快速层~16–64 MiB/TensorCore; align=VmemAlignmentBoundaryInBytes()granule=VmemWordSizeBytes() (Target+0x50C);银行 JF8/PF16/VF32/GL32BestFitAllocator / MSA + ProgramMemoryAllocatorvmem-allocator.md
4cmem常量内存:Pufferfish只读大部分操作数池(专用联发加载槽)CmemSizeBytes() (Target+0x460);字=颗粒=CmemWordSizeBytes()(Target+0x510,~16 B PF);仅银行 PF=32BestFitAllocator / MSA (xla_tpu_cmem_*)cmem-pool.md
5smem0 (0x0)标量内存:SPU 溢出/参数存储、循环计数器、完成描述符SmemSizeBytes() (Target+0x470);字=SmemWordSizeBytes()=4 B (Target+0x508);银行 JF2/PF8/VF8/GL8BestFitAllocator / ProgramMemoryAllocator(操作码驱动,不是 MSA)smem-标量-内存.mdsmem-register-window.md
6sflag204 (0xCC)同步标志寄存器文件:DMA 完成/屏障握手字、原子计数器/完成位字粒S32; SflagWordSizeBytes()(Target+0x504),log2缓存Target+0x4c8byte_off = 4·nBestFitAllocator(大小)+固定数量空间分区sflag-protocol.md
7imem214 (0xD6) †指令存储器:捆绑定序器读取芯片_零件定序器内存空间枚举.md
8barna_core_bmemBarnaCore(嵌入引擎)批量暂存器芯片_零件;仅限 PXC 系列BarnaCore内存空间枚举.md
9barna_core_smemBarnaCore 标量暂存器Target+0x47C尺寸,+0x480底座,+0x51CBarnaCore(BarnaCoreSflagImmPtr,范围蹦床)smem-标量-内存.md
10barna_core_sflagBarnaCore 同步标志层(与 TC SFLAG 不同)Target+0x478 (BarnaCoreSflagSizeBytes)BarnaCoresflag-protocol.md
11barna_core_imemBarnaCore指令存储器芯片_零件BarnaCore内存空间枚举.md
12sparse_core_sequencer_sflag223 (0xDF) ‡SC 定序器同步标志组芯片_零件; SC 音序器SparseCore 定序器sflag-protocol.md
13host主机驻留缓冲区(传输源/接收器;MSA 卸载溢出目标)主机DRAMPremappedMemoryManager / tsl::BFCAllocator 超过 posix_memalign概述.md
14sparse_core_sequencer_smem224 (0xE0) ‡SC 定序器标量暂存器(众所周知的常数:chip_idreplica_id,...)SCS SMEM 64 KiB VF/GL/GF 上的硬立即数SparseCore 定序器smem-标量-内存.md
15sparse_core_private_stack_hbm203 (0xCB)每个 SC 私有堆栈由 HBM 雕刻而成HBM 支持HBM 支持内存空间枚举.md
16pinned_hbm用于主机可见 DMA 的页面固定 HBM(重新打包程序可能不会重新定位)1024 B DMA底板+主机引脚HBM(固定)hbm-dma-alignment.md

注意 — † AS-id 列将每个 TensorCore 层映射到物理上对应的SparseCore 池,而不是身份。 imem(LLO 7) ↔ SC timem (AS 214) 和 sparse_core_sequencer_sflag/_smem (LLO 12/14) ↔ SC sflag_scs/smem_scs (AS 223/224) 是物理身份对应,而不是算术转换。 ‡ SparseCore 定序器库是每个 SCS 的变体; AS-id 带还承载每块(AS217 sflag_tileAS219 smem_tile)和芯片共享(AS202 spmem)SC 池,这些 SC 池具有 LLO MemorySpace 等效项(它们仅存在于 SparseCore LLVM 降低内)。请参阅下面的 SparseCore AS 部分。

明白了 — 0x21ce6b08 处的 MemorySpaceToString不会停在索引 16 处。索引 17/18/19 解析为 absoluteheap_relative (0x8678cad),并且stack_relative (0x8678cbb) — 附加到同一字符串数组的指针相对性标签,不是内存池。它们属于LloAddress搬迁模型。按字符串表长度调整枚举大小或将 absolute/heap_relative/stack_relative 视为层的重新实现是错误的:规范区域枚举恰好是 17 个值。


LLO MemorySpace 枚举(TensorCore 操作数标签)

解码器和地面实况

MemorySpaceToString 是整数→区域映射的基本事实:它是没有边界检查的单索引负载,因此枚举值是直接数组索引,并且超长表与相对性标签共享。

c
// 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:49

sflag → 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);他们同意 0112..16。完整的重映射表和屏蔽的 DMA 有效性门位于 内存空间枚举.md 上;将原始字段编号与运行时枚举合并的(反)序列化器会默默地重新标记每个 vmem/cmem/hib 缓冲区。

规范分配,四种锚定方式

注意 — 字节精确序数分配是本页顶部的 17 值表,以上面的四种独立方式锚定(MemorySpaceToStringMemorySpaceToDriverResourceMakeCmemConstantMakeSparseCoreSequencerSmemConstant)。重新实现者最常出错的边界情况:sflag = 6(不是 7)与 imem = 7sparse_core_sequencer_sflag = 12host = 13sparse_core_sequencer_smem = 14(定序器 SFLAG/SMEM 序号相邻 — host 位于它们之间); hib = 2pinned_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 间隙)。转换是字节精确且自逆的:

c
// 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=0kPinnedHbm=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) — 第十七部分 — 附录