Skip to content

CMEM 常量内存池

本页中的所有地址均适用于 libtpu-0.0.40-cp314 wheel 中的 libtpu.so(构建 libtpu_lts_20260413_b_RC00,build-id md5 89edbbe81c5b328a958fe628a9f2207d)。该镜像被 strip;反混淆后的 C++ 符号名按原文引用。每个 codename 的 CMEM 字节大小位于嵌入的 *chip_parts.binarypb 资源中,而不在 C++ 中;下文的每个数值大小均按注明来源给出。其他版本会有所不同。

摘要

CMEM("constant memory",MemorySpace::kCmem = 4)是一个片上 SRAM 操作数池,作为一等内存层级只存在于一个量产 codename:Pufferfish (PXC, TPU v4)。它就是 memory-space taxonomy 所称的 “a Pufferfish-only read-mostly operand pool”,也是 Pufferfish TensorCore 能在每个 bundle cycle 获取两个向量操作数的原因:专用的 TensorCoreCmemLoad 槽会在与常规 VMEM VectorLoad 相同的 51-byte bundle 中发出 CMEM 读取,从而使 MXU 操作数获取带宽翻倍。

本页只负责三件事:(1) CMEM 池布局,包括 allocator Config、byte/word/bank 寻址模型,以及每程序 image 和 stack 的位置;(2) 逐代 sizing,即哪些 codename 拥有 CMEM,以及 size、word、bank count 如何暴露;(3) 常量打包,即编译器选择把什么放入 CMEM 以及这些字节如何到达那里。片上 SMEM 模型见 smem-scalar-memory.md;层级 taxonomy 和共享 BestFitAllocatoroverview.md;位精确的 cmem_load bundle slot 位于 ISA 侧(slot-cmem-load-pf.md, bundle-pf-51b.md)。本页链接这些内容但不重复。

重新实现者需要内化以下契约:

  • CMEM 不是单独的 allocator class。 没有 CmemAllocator。CMEM 使用与其他层级相同的双栈模型(overview.md §1):编译时的 ProgramMemoryAllocator::AllocateBytes(MemorySpace::kCmem, …) 和运行时的 tpu::BestFitAllocator 实例,仅由一个 32-byte Config{base_offset, end, alignment, granule} 区分。
  • CMEM sizing 是 Target 上的两个标量字段。 Target::CmemSizeBytes()Target+0x460, uint64)是总字节数;Target::CmemWordSizeBytes()Target+0x510, uint32)是 word,也就是 allocator 的 alignment granule。二者在启动时由 chip_parts.binarypb 填充;任何 codename 的 Target subclass 都不会覆盖它们。
  • 只有 MemBanks(kCmem) 返回值时,CMEM 才是真实存在的。 只有 PufferfishTarget::MemBanks(kCmem) 返回一个数(32);其他每个 codename 上的 MemBanks(kCmem) 都是 LogMessageFatal。全部逐代 CMEM 差异都归结为数据:MemBanks(kCmem) 的返回、PufferfishTarget::LocalDmaBandwidth*Cmem overrides 的存在、pxc::isa::*Cmem* opcode family 的存在,以及 chip_parts.binarypb 提供的 size triple。
  • 常量由 MSA 打包,并由 program-prologue DMA 填充。 放置决策由 MSA pass 作出,并受 xla_tpu_cmem_* flag family 门控;字节通过编译后程序 prologue 中发出的 kDmaHbmToCmem / kDmaVmemToCmem 到达,不是在 NEFF 加载时到达。
内存空间xla::jellyfish::MemorySpace::kCmem = 4(name table @ 0x21ce6b08
总大小 accessorTarget::CmemSizeBytes() @ 0x1d615e20*(uint64*)(this+0x460)
Word/granule accessorTarget::CmemWordSizeBytes() @ 0x1d617320*(uint32*)(this+0x510)
Banks(仅 Pufferfish)PufferfishTarget::MemBanks(kCmem) @ 0x1d493900 = 32{16,32,8}[MS-3] @ rodata 0xb5305c8
编译时 placerProgramMemoryAllocator::AllocateBytes(MemorySpace::kCmem, …) @ 0x1c629e40
运行时 allocatortpu::BestFitAllocatorConfig{base=0, end=CmemSizeBytes, align=granule=CmemWordSizeBytes});由 CreateFromProto @ 0x1c631f20 重新水合
地址缩放LloRegionBuilder::CmemAddrScaled @ 0x1d539980(byte→word 由 CmemWordSizeBytes 完成;kCmem guard)
常量形式LloAddress::MakeCmemConstant(long) @ 0x1d60ba20LloAddress(MemorySpace=4, off)
放置门控parent->module()->target().CmemSizeBytes() > 0(在 CreateVectorCmemResult @ 0x1d4d99a0 中断言)
MSA 总开关FLAGS_xla_tpu_cmem_memory_space_assignment @ 0x223c1750
逐代可用性仅 Pufferfish(PXC, TPU v4);DF/JF/VF/GLC/GFC 上 MemBanks(kCmem)LogFatal
置信度CONFIRMED(byte-anchored, decompile-verified),除非某行或 callout 另有说明

1. CMEM 池布局

目的

CMEM 是一个扁平的 per-TensorCore SRAM 区域。在 allocator 层级,它是从 offset 0 开始按字节扁平的;在 LLO bundle 层级,它是按 word 编址的;在 issue 时,它由indirect-state 驱动。重新实现者必须复现全部三种视图,因为 byte→word 转换发生在 address builder 中,而不是 issue 时,bank 坐标也从 word index 推导。

allocator Config

CMEM 是由通用 32-byte MemoryAllocator::Configoverview.md §3)构造的一个 tpu::BestFitAllocator。对 CMEM 层级而言,四个字段是:

c
tpu::MemoryAllocator::Config {
    base_offset_in_bytes_  = 0,                       // CMEM starts at sub-tile address 0
    allocatable_range_end_ = Target::CmemSizeBytes(), // *(uint64*)(Target+0x460)
    alignment_in_bytes_    = Target::CmemWordSizeBytes(), // *(uint32*)(Target+0x510)
    granule_in_bytes_      = Target::CmemWordSizeBytes(), // alignment == granule
};
```text

ctor(`0x1e817500`)断言 `alignment % granule == 0` 且 `alignment` 是 2 的幂;对 CMEM 而言二者是同一个值,因此两个不变量都平凡成立。容量是 `end − base = CmemSizeBytes()`。CMEM 没有 `base_offset` 预留,也没有 `ReserveBottomOfMemory` 调用;与 HBM 不同,它没有 DMA-floor / compile-time-alignment 分裂。

> **NOTE —** CMEM 没有类似 scoped-VMEM 的 **scoped-limit machinery**。不存在 `Target::OverlayReservedCmemBytes`、`DefaultPlatformScopedCmemBytes`、`RequiredPostModuleScopedCmemBytes`。`LloRegionBuilder::AllocateScopedCmem` (`0x1d5181a0`) 只是进入共享 `AllocateScopedMemory(shape, MemorySpace::kCmem, name)` (`0x1d517c20`) 的薄 trampoline。Scoped-CMEM 分配只受 `CmemSizeBytes() − (used chunks × chunk_bytes)` 限制。

### 寻址模型

| 层级 | 单位 | 机制 |
|---|---|---|
| Allocator | **byte** offset, base 0 | `BestFitAllocator` 给出相对 `base_offset = 0` 的字节偏移 |
| Bundle / LLO | **word** index | `CmemAddrScaled` (`0x1d539980`) 将 byte address 除以 `CmemWordSizeBytes`(传给 `AddrScaled` `0x1d538880` 的 `Granule` arg);bundle `Offset` 字段携带 *word* index |
| Bank (PF) | `(word_index) mod 32` | word index 的低位选择 `MemBanks(kCmem)=32` 个 bank 之一 |
| Issue | **indirect-state slot** | `CmemIndirectState` 预构建 16-byte slots;bundle `base_address` 字段携带 slot index |

`CmemAddrScaled` 是字节 allocator 和 word-indexed bundle 之间的连接点。其反编译函数体在缩放前断言 address operand 是 `kCmem`:

```c
// LloRegionBuilder::CmemAddrScaled  @0x1d539980  (verbatim-derived)
LloCheckForFailure<MemorySpace, MemorySpace, kCmem>(...);   // v13[0] = 4 == kCmem
// on failure: UpdateStatus("base->memory_space() == MemorySpace::kCmem",
//                          "platforms/xla/service/jellyfish/llo_region_builder.cc", 4965)
return AddrScaled(this, byte_addr, base, off, /*Granule=*/0 → CmemWordSizeBytes, ...);

常量形式 LloAddress::MakeCmemConstant(long off) (0x1d60ba20) 会直接构建 LloAddress(MemorySpace=4, off)(constructor 0x1d60b980, esi=0x4)。不存在 CMEM register file:CMEM load 的目的地是 VS / VEX register file 中的 Vreg;CMEM 纯粹是操作数池加一个小型可变 stack。

每程序 image 和 stack

CMEM 内容是每程序 image,不是启动时常量池。其中包含两个区域:

  • image 头部的 indirect-state table,由 Target::CmemStackBaseTableWordOffset() (0x1d6185c0) 锚定。每个条目都是程序启动时由 CmemIndirectStateFactory 构建的 16-byte indirect-state record(full Pufferfish 上为 pfc::b0::Cmq16BIndirectStateFactory,Pufferfish-Lite 上为 plc::Cmq16BIndirectStateFactoryCmq16B 名称是推断 16-byte word 的来源)。
  • 位于 Target::CmemStackStartWordOffset() (0x1d618660) 的小型每程序 stack,持有运行时可变标量(由 kVectorCmemLoadAndPop 消费的 loop counters,即 load-and-post-increment streaming-read opcode)。rodata 锚点是 "cmem stack start""cmem stack base table"

GOTCHA — CMEM 是每程序 scratch,会在每次程序切换时被覆盖,不是 pinned 的全芯片常量存储。CMEM allocator 由 CreateFromProto (0x1c631f20) 按程序实例化;image 在程序 prologue 中从 HBM 填充;下一个程序的 prologue 会覆盖它。不存在编译后程序之外的专用 “CMEM load engine”;每个 CMEM 字节都由 LLO 发出的 DMA descriptor 或 VPU store opcode 写入。这就是为什么 CMEM 持有的是一个程序的 weights/LUTs working set,而不是整个模型。


2. 逐代 CMEM Sizing

目的

CMEM 是否存在是按 codename 决定的,并由数据加三个小的 Target overrides 决定,而不是 allocator 中的任何 TpuVersion 分支。驱动 CMEM 的重新实现者必须精确复现这个门控:仅当 CmemSizeBytes() > 0 MemBanks(kCmem)LogFatal 时,才尝试 CMEM 放置;在已发布的 0.0.40 runtime 中,这只包括 Pufferfish。

sizing accessors(反编译确认)

两个 accessor 都是在 base Target 上的直接字段读取,没有 per-codename override

c
// Target::CmemSizeBytes()      @0x1d615e20
return *((uint64_t*)this + 140);   // 140 * 8  = 0x460   — total CMEM bytes / core

// Target::CmemWordSizeBytes()  @0x1d617320
return *((uint32_t*)this + 324);   // 324 * 4  = 0x510   — word = alignment = granule
```text

不存在 `Target::CmemWordSizeLog2` 字段(SMEM 在 `+0x4CC` 有一个,因为 LLO bundle packing 会为 SMEM 发出 byte→word shift;CMEM 的 byte→word 转换在 `CmemAddrScaled` / indirect-state classes 内完成,它们会硬连线 granule)。

`PufferfishTarget::MemBanks(MemorySpace)` 是门控一切的唯一 override(反编译 @ `0x1d493900`):

```c
// PufferfishTarget::MemBanks(MemorySpace ms)   @0x1d493900
unsigned v4 = ms - 3;                 // kVmem=3 → 0, kCmem=4 → 1, kSmem=5 → 2
if (v4 >= 3)                          // ms >= 6 (sflag, …)
    LogMessageFatal("target_pufferfish.h", 228,
                    "Unsupported memory space specified for MemBanks()");
return qword_B5305C8[v4];             // {16, 32, 8}  → kCmem ⇒ 32

base Target::MemBanks 和每个非 Pufferfish override 都会让 kCmem 落入 LogMessageFatal 分支;MemBanks(kCmem) 在 JF/VF/GL/GF 上根本没有有效返回值。

逐 codename CMEM 矩阵

Sizes 来自启动时的 chip_parts.binarypb;每个 codename 的 alignment = granule = CmemWordSizeBytes()。Pufferfish bandwidth/latency immediates 由 PufferfishTarget::LocalDmaBandwidth* / InitialDmaLatencyInNs 函数体解码,并在这里对照反编译重新验证。

TpuVersion / familyTarget classCMEM size (B)Word / granule (B)MemBanks(kCmem)CMEM ISA opcodesBW VMEM→CMEM (GB/s)InitialDmaLatency (kCmem, ns)
Dragonfish (DF)DragonfishTargetchip_parts (≈ 0)chip_partsn/a (LogFatal)none0 (base, unmodelled)240 (inherited)
Jellyfish (JF)JellyfishTargetchip_parts (≈ 0)chip_partsn/a (LogFatal)none0 (base)240 (constant)
Pufferfish (PXC, TPU v4)PufferfishTargetchip_parts (non-zero)~16 (Cmq16B)32dedicated PXC slot + VS + Misc112150
Viperfish (VFC)ViperfishTargetchip_parts (= 0)chip_partsn/a (LogFatal)emitters only, lower to VL/VS0 (base)1200 / 0 (lite)
Ghostlite (GLC / glc, v6e)GhostliteTargetchip_parts (= 0)chip_partsn/a (LogFatal)none (no gxc::glc::isa::*Cmem*)0 (base)1200
6acc60406 (GFC / gfc, TPU7x)GhostliteTargetchip_parts (= 0)chip_partsn/a (LogFatal)none (no gxc::gfc::isa::*Cmem*)0 (base)1200

GOTCHA(字面字节大小为 LOW)— 字面的 per-codename CMEM 字节大小位于嵌入的 chip_parts.binarypb proto 的 TpuMemoryParts 记录中,尚未从 binary 中提取;C++ 只是从 Target+0x460 盲读。Pufferfish 的 word/granule “16 B” 是从 Cmq16BIndirectStateFactory template-parameter 名称推断的,不是从 proto 读取的。公开 Pufferfish 材料以 per-TensorCore-MiB 量级描述 CMEM,但重新实现者应把字面 size 和 word 视为 chip_parts 提供的数据,而不是 binary-derived constants。

NOTE — Pufferfish 发布了两个 sub-variants,二者都在同一个 PufferfishTarget C++ class 背后承载完整 CMEM 逻辑:pfc::b0(canonical Pufferfish-A)和 plc(Pufferfish-Lite),只通过它们的 CmemIndirectStateFactory<…Cmq16BIndirectStateFactory> specialization 以及(可能的)不同 chip_parts.binarypb CMEM size 区分。C++ Target class 不在二者之间分支。

为什么只有 Pufferfish

专用 CMEM bundle slot 存在,是因为只有 Pufferfish 建模了 CMEM。结构性原因(反编译确认):只有 PufferfishTargetMemBanks(kCmem) override 为真实值,也只有 PufferfishTargetLocalDmaBandwidth*Cmem virtuals 从 base 0.0 改写。专用 cmem_load slot 与 bundle 中的 vector_load slot 分离,因此一次 CMEM read 和一次 VMEM read 可在同一 cycle co-issue,也就是 v4 双操作数获取 datapath。位精确 slot 布局见 slot-cmem-load-pf.md

Pufferfish CMEM cost-model immediates 由反编译的 movabs/return 函数体重新解码(IEEE-754 doubles):

Pair (PufferfishTarget::…)AddrRaw immediateValue (GB/s)
LocalDmaBandwidthVmemToCmem0x1d4943e00x40918400000000001121.0
LocalDmaBandwidthCmemToVmem0x1d4944400x40A24600000000002339.0
LocalDmaBandwidthCmemToSmem0x1d4944800x404100000000000034.0
LocalDmaBandwidthSmemToCmem0x1d4944e00x404100000000000034.0
LocalDmaBandwidthCmemToHbm0x1d4944200x4090E000000000001080.0
LocalDmaBandwidthCmemToCmem0x1d4944600x4092A400000000001193.0
InitialDmaLatencyInNs(kCmem)0x1d493d00table [555.0, 50.0][ms==4]50 ns

这种非对称(读侧 2339 GB/s vs. 写侧 1121 GB/s)反映了 CMEM 物理总线的读路径大约拥有两倍线宽;50 ns startup 比 555 ns VMEM/HBM startup 低一个数量级,反映了 CMEM 的 per-tile-resident 短总线。完全不存在 LocalDmaBandwidthHbmToCmem accessor;HBM↔CMEM 流量按 VMEM 桥接公式建模(HBM→VMEM latency + VMEM→CMEM bandwidth)。


3. 常量打包 — 什么进入 CMEM 以及如何进入

目的

CMEM 是 compile-time-known、read-mostly 数据的 “tile-resident operand store”。本节说明放置标准(MSA 选择打包什么)和填充路径(字节如何到达那里)。读取这些字节的 load 的 bit-level encoding 位于 ISA 页面。

被打包的内容

根据 PXC ISA opcode family、xla_tpu_cmem_* flag family 和 runtime error strings 恢复:

打包内容为什么用 CMEM来源证据
固定 shape 模型的 Convolution-filter / matmul weights程序启动时流入一次,之后多次读取以供给 MXU operand pipe主要的 kDmaHbmToCmemTensorCoreCmemLoad 流程
Look-up tables(activation, saturation, quantisation)materialise-once, read-many-per-elementLUT placement;高 CMEM read BW
Indirect-state descriptor blocks驱动 vectorised reads 的 indirect-address resolutionCmemIndirectState(16-B Cmq16B records)
All-reduce staging buffers在 collectives 期间为 operand staging 释放 VMEMFLAGS_xla_tpu_scoped_cmem_for_all_reduce @ 0x223b8de8
MXU result direct-to-CMEM绕过 matmul output 的 VMEM 往返kVectorCmemResultCreateVectorCmemResult @ 0x1d4d99a0
HLO output buffers(experimental)将配置比例的 CMEM 用于 top-level outputsFLAGS_xla_tpu_experimental_cmem_fraction_for_hlo_outputs @ 0x223b8cc8
CMEM stack scalars(loop counters)运行时可变;由 load-and-pop 流式读取kCmemStackOffset, kVectorCmemLoadAndPop
In-CMEM copy spans (CmemSpan)sliding-window sequential readsFLAGS_xla_tpu_allow_in_cmem_copy @ 0x223b30d0(默认关闭)

MSA 放置决策

打包由 Memory-Space Assignment pass 决定,也就是放置 VMEM 的同一个 kAlternate-tier coloring(overview.md §4),并受与 xla_jf_vmem_* 一一对应的 per-tier xla_tpu_cmem_* flag family 门控。总开关是 FLAGS_xla_tpu_cmem_memory_space_assignment (0x223c1750);字节上限是 FLAGS_xla_tpu_max_cmem_used_by_memory_space_assignment (0x223ae230);prefetch/eviction caps、repack/retry counts 和 overlap ratios 构成其余 family(0x223c0250 … 0x223c1e78)。

两层拉扯(由 CmemSizeBytes() > 0 反编译门控,见下):

HloValue characteristic胜出
MXU primary operand(matmul A/B),需要 VS-slot ports该 codename 的 FastMemorySpace() — VF/GL 上为 VMEM,JF 上为 HBM,PF 上为 CMEM(见下面逐 codename 拆解)
固定 shape conv 的 weight tile;LUT;quant table(read-mostly, small)CMEM(高 read BW,专用 bundle slot)— 仅 Pufferfish
Activation tile(随 batch 改变)VMEM
All-reduce stagingxla_tpu_scoped_cmem_for_all_reduce 则 CMEM,否则 VMEM
HLO top-level output默认 HBM;若 …cmem_fraction_for_hlo_outputs > 0 则 CMEM
任何地方都没有 live-range headroomHBM(spill, fetch on demand)

FastMemorySpace()逐 codename 且经反编译验证的:JellyfishTarget::FastMemorySpace() (0x1d491a20) 返回 kHbm(=1)(Jellyfish 没有片上 fast operand tier);ViperfishTarget (0x1d49c3c0) 和 GhostliteTarget (0x1d499000) 都返回 kVmem(=3);而让整个 CMEM datapath 存在的关键一项,PufferfishTarget::FastMemorySpace() (0x1d495f00) 返回 kCmem(=4)。在 Pufferfish 上,CMEM 就是 fast tier:单条 mov $0x4,%al; ret。因此 MSA 只在 Pufferfish 上偏向把 read-mostly tiles 放入 CMEM,因为 active Target 同时宣称 kCmem fast space 和非零 LocalDmaBandwidthCmemToVmem

NOTE(CONFIRMED gate)— 任何宣称零 CMEM 的 codename 都会短路整个 CMEM 放置路径。反编译的 LloInstruction::CreateVectorCmemResult (0x1d4d99a0) 断言 parent->module()->target().CmemSizeBytes() > 0,否则 LogMessageFatal;因此除非 active Target 具有非零 CMEM,否则 CMEM-result write 不可达。相同不变量也保护 MSA,并伴随 rodata diagnostic "CMEM is not supported."。省略 CmemSizeBytes() > 0 前置条件的重新实现,会把 CMEM 放置错误路由到无法支撑它的 codename。

填充路径

CMEM 由 program-prologue DMA 填充,而不是在 NEFF / image load 时填充。编译后的 XDB 程序把 CMEM image 声明嵌入为 ProgramMemoryMetadata_Allocation 条目,memory_space = kCmem,与 VMEM/HBM/SMEM 完全一样;CreateFromProto (0x1c631f20) 将它们转化为 runtime allocator offsets。字节随后通过编译后的 prologue 到达:

填充机制EmitterCost-model BW (PF)
HBM→CMEM bulk fill(weights, LUTs)LloRegionBuilder::DmaHbmToCmemInBytes @ 0x1d576e60kDmaHbmToCmemVMEM-bridged(无 direct HbmToCmem BW)
VMEM→CMEM staged fillLloRegionBuilder::DmaVmemToCmemInBytes @ 0x1d576c801121 GB/s
In-program VPU storeTensorCoreVectorStore_CmemStore / …NoOffset(折叠进 VS slot)(VS write port)
MXU result direct writekVectorCmemResultCreateVectorCmemResult @ 0x1d4d99a0(result-buffer drain)
SMEM→CMEM scalar stagingDmaSmemToCmemInBytes @ 0x1d577220(只有这个方向有 emitter;没有 DmaCmemToSmemInBytes34 GB/s

bulk fill 后,CmemIndirectState ctor 会在 image 头部构建 indirect-state vector,使 VPU bundle slot 能对 resident tiles 发出 TensorCoreCmemLoad。回写到 HBM 的 eviction(MSA spill path)使用 DmaCmemToHbmInBytes (0x1d577040)。

GOTCHA — read-only 是约定,不是硬件写保护。 CMEM “read-mostly” 只是一种编译器分类:ISA 具有显式 CMEM write opcodes(VectorCmemStore, VectorCmemStoreNoOffset),有七条 DMA write paths 以 CMEM 为目标,MXU result drain 也会写它。LSRA-v2 将 compile-time-constant CMEM loads 视为 rematerialisable,MSA 将 read-mostly tiles 偏向 CMEM,但如果有 bug 的程序覆盖了 constant region,后续读取会被静默破坏;不会有硬件 fault。保护完全在 SSA / dataflow 层级。

耗尽处理

编译时 CMEM 耗尽模式(来自 runtime error strings):

  • 请求大小超过容量result.memory_space_assignment_size_in_bytes <= target.UserAllocationSharedMemoryLimitBytes(MemorySpace::kCmem) (0x1d616680);违反时 LogMessageFatal"Requested Cmem size for memory space assignment (…)")。
  • Target 宣称零 CMEM — 上述 CmemSizeBytes() > 0 gate;发出 "CMEM is not supported." 并跳过 CMEM(或在 custom-call 要求 CMEM 时编译失败)。
  • 越界 byte address — 每次发出 CMEM operand 时都断言 byte_address < target().CmemSizeBytes();违反时 LogMessageFatal
  • MSA 无法放置 — 最多重试 xla_tpu_cmem_max_retries 次,然后 fallback 到 HBM 并记录软 diagnostic "Ignoring cmem allocation: …" / "Ignoring cmem allocation storage"
  • CmemSpan 被禁用cmem_indirect_state_factory.h 中的 use_cmem_span_ == true / !use_cmem_span_ 不变量;当 xla_tpu_allow_in_cmem_copy 关闭却请求 span 时,会以 "Disabled cmem span" LogFatal

运行时耗尽走标准 BestFitAllocator::Allocate ResourceExhaustedError 路径(hbm-allocator.md),这种情况很少见,因为 CMEM image 在编译时已完全 materialised,并在加载时 replay。


交叉引用

  • overview.md — 六区域 memory-space taxonomy、MemorySpace enum(kCmem=4)、共享 BestFitAllocator,以及本页针对 CMEM 专门化的 compile-time→runtime hand-off
  • smem-scalar-memory.md — sibling 片上 scalar tier(kSmem=5);SMEM↔CMEM 34 GB/s staging pair,以及缺少 CmemWordSizeLog2 的对比
  • vmem-allocator.md — CMEM 在 MSA 中竞争的 kAlternate fast tier;逐代 VMEM word/bank Config
  • hbm-allocator.md — CMEM 共享的通用 best-fit allocate/deallocate 算法;运行时 ResourceExhaustedError 路径
  • tpu-buffer-layout.md — 逻辑 XLA buffer 如何映射到这些层级中的物理 offsets
  • slot-cmem-load-pf.md — 位精确的 Pufferfish cmem_load bundle slot(本页引用的读取访问路径)
  • bundle-pf-51b.md — 专用 CMEM-load slot 所在的 51-byte Pufferfish TensorCore bundle
  • memory-space-enum.md — ISA / operand-tag 层级的 LLO MemorySpace enum
  • msa-overview.md — 通过 xla_tpu_cmem_* flag family 为 CMEM 着色的 placement pass
  • back to index — Part X — On-Chip Memory & DMA