Skip to content

SMEM 寄存器窗口

本页中的每个符号、偏移和地址都从 libtpu-0.0.40-cp314 wheel 中的 libtpu.so 逐字节读取而来(构建 libtpu_lts_20260413_b_RC00,build-id md5 89edbbe81c5b328a958fe628a9f2207d)。该镜像剥离;反混淆后的 C++ 符号名均逐字引用。.text VA 等于文件偏移 0xe63c000.rodata VA 等于文件偏移 0x84a0000。其他版本会有所不同。

摘要

"SMEM register-window" 这个短语并没有命名 libtpu.so 中的任何东西。在该二进制的 2.9M 个字符串或 1.2M 个符号里,都不存在 SmemRegisterWindowSregWindowRegisterWindowWindowBasewindow_basereg_windowSmemSpillRegister 这样的符号或字符串。本页用于回答这个短语暗含的问题:"是否有一个 SMEM 窗口像 SPARC 寄存器窗口或旋转 ISA 寄存器文件那样映射到标量寄存器文件中?" 答案是没有SPU 标量寄存器文件是一个扁平的、受硬件边界限制的 32 项文件,使用 5 位索引,没有 base/size 窗口寄存器,没有 bank 选择器,没有 overflow/underflow trap。SMEM 是它的溢出后备存储,通过普通的标量 load/store opcode 访问(SMEM 标量内存),而不是通过窗口映射访问。

实际存在的东西,也就是听到 "SMEM register-window" 的重实现者很可能被指向的东西,是三个各自命名的机制,其中没有一个会给 SREG 文件开窗口。它们中的两个确实给内存开窗口(其中一个可以位于 SMEM);第三个给谓词寄存器开窗口。最贴近该短语的机制是 CBREG(circular-buffer register):单个寄存器持有一个指向片上内存的 {base, offset, size} 窗口,并产生自动前进、末尾回绕的地址流。CBREG 是包含内存窗口的寄存器,正好是"寄存器上的窗口"的反向。

本页是内存子系统的消歧说明。它给出否定结论(SREG 文件没有窗口,SMEM 没有寄存器窗口机制),列举三个真实的 "window",说明每个实际给哪类资源开窗口,并展示它们分别如何与 SMEM 相关。CBREG opcode 位布局由 CBREG 循环缓冲寄存器负责,SPU slot 字段网格由 SPU / 标量 Slot负责,标量谓词文件由 谓词 Slot负责,SMEM 分配器由 SMEM 标量内存负责。

对重实现而言,契约是:

  • 否定结论就是架构。 重实现不得为 SREG 文件分配 window-base/window-size 寄存器对,不得实现 SPARC 风格的窗口 overflow/underflow trap,并且必须像 libtpu 一样显式地把 SREG 压力 spill 到 SMEM(LSRA-v2)。SREG 索引是 5 位;共有 32 个;这就是整个文件。
  • "Register window" 在三类资源上被重载使用。 CBREG {base,offset,size} 内存窗口(持有内存窗口的寄存器)、流水线 OperandWindow(暂存在 VMEM / SMEM / HOST 中的张量操作数子 tile),以及旋转谓词文件(TPU 上唯一真正的硬件"寄存器上的窗口")。交付物就是知道哪一个是哪一个。
  • SMEM 关联是真实的,但都是间接的。 SMEM 会出现在 CBREG 可能的地址空间中,会作为 OperandWindow 的合法放置位置,也会作为 fixed-window pipeline emitter 中动态窗口大小的可选存储;但这些情况没有任何一个把窗口映射到标量寄存器文件之上
SREG 文件(被错误称为有 "window" 的对象)扁平 32 项,5-bit 索引;边界由 ProtoUtils::EncodingToScalarRegister @ 0x1e871e40 强制执行(idx > 0x1F → error)
SREG bank 名称(没有窗口化变体)SC_SCS_SREGS, SC_TAC_SREGS, SC_TEC_SREGS (.rodata) — 不存在 ROTATING/WINDOWED/BANKED SREG bank
CBREG(持有内存窗口的寄存器)banks SC_{SCS,TAC,TEC}_CBREGS_{BASE,OFFSET,SIZE};16/sequencer;详情 → cbreg.md
流水线 OperandWindow(内存子 tile)xla::jellyfish::SetWindowParams(…OperandWindow&, Shape const&, mlir::MemRefType, …) @ 0x112658a0;space tag 存在 OperandWindow +0x4C1
OperandWindow space tag0x3 = kVmem, 0x5 = kSmem, 0xD = HOST(从 SetWindowParams 读取)
旋转 PREDICATE 窗口(真正的寄存器窗口)banks SC_SCS_ROTATING_PREGS, SC_TEC_ROTATING_PREGS;后端 gate TPUGfcSubtarget::hasRotatingPredicates() @ 0x13c62c20 = 1(仅 6acc60406
SREG overflow 处理软件 spill 到保留 SMEM(LSRA-v2);没有硬件窗口,没有 overflow trap
否定搜索0 hits: SmemRegisterWindow / SregWindow / RegisterWindow / WindowBase / window_base / reg_window / SmemSpillRegister; 0 TPU hits: window_overflow / window_underflow / register_window_trap
置信度CONFIRMED(字节锚定),除非某行或标注另有说明

1. 问题与否定结论

目的

有经典架构背景的读者看到 "SMEM register-window" 时,会把它理解成两种熟悉事物之一:(i) SPARC 风格的大物理寄存器文件滑动窗口,把寄存器的一个窗口映射到架构名 r0..r31,并有硬件 save/restore trap 由内存 spill 区支撑;或 (ii) 旋转寄存器文件(IA-64 风格),其中架构寄存器名会按每次循环迭代前进的窗口基址进行偏移。两者都可以叫作"映射到标量寄存器文件中的内存/寄存器窗口"。TPU 上两者都不存在。

二进制说明了什么

SPU 标量寄存器文件是扁平的。把 ScalarYEncoding 操作数转换为物理 SREG 索引的编码器 platforms_deepsea::jellyfish::isa::ProtoUtils::EncodingToScalarRegister0x1e871e40)会拒绝任何大于 0x1F 的索引:

c
// EncodingToScalarRegister @ 0x1e871e40 (decompiled, condensed)
if ( a2 > 0x1F )                 // index >= 32 is illegal
    return InvalidArgument(      // absl::Status, not a trap; proto_utils.cc:917
        "Input is not a valid register encoding. "
        "Input must be in the range [%d, %d]", 0, 31);
return /* flat index a2 */;       // status OK, payload = flat index a2
```text

架构 SREG 正好有 32 个,用 5 位字段寻址;没有 window-base 寄存器加到索引上,也没有 bank 选择器来扩大名称空间。SparseCore register-bank 分类从另一个方向确认了这一点:标量 bank `SC_SCS_SREGS`、`SC_TAC_SREGS`、`SC_TEC_SREGS` 存在于 `.rodata` 中,而对任何 `SC_*_ROTATING_SREGS` / `SC_*_WINDOWED_SREGS` / `SC_*_BANKED_SREGS` bank 的搜索都返回 **zero** hits。谓词 bank *确实*有旋转变体(§4);标量 bank 没有。

> **NOTE —** [内存概览](overview.md) §1 用一句话说明了这一点:"'register window' is a misnomer for every on-chip tier here. SMEM, CMEM, and SFLAG are all flat byte/word arrays … Scalar register windowing lives on the SREG file (allocated by LSRA-v2), and SMEM is merely its spill backing store." 本页就是该句背后的证明和枚举。

### 缺失是穷尽性的

该短语的字面拼写已经在整个二进制中搜索过,均不存在:

| 搜索 token | `libtpu.so` 中的 hits | 含义 |
|---|---|---|
| `SmemRegisterWindow`, `SregWindow`, `SmemRegisterFile`, `SmemSpillRegister` | 0 | 没有命名任何 windowed-SMEM register file |
| `RegisterWindow`, `RegWindow`, `WindowBase`, `window_base`, `reg_window` | 0 | 没有任何类型的 register-window primitive |
| `window_overflow`, `window_underflow`, `register_window_trap`, `save_restore_window`, `spill_window`, `fill_window` | 0 TPU(只有 `zlib_rs::deflate::fill_window`,无关) | 没有 SPARC 风格的 window-trap 机制 |

唯一的 `fill_window` hit 属于静态链接的 `zlib_rs`,与寄存器无关。overflow/underflow/trap token 的缺失是决定性证据:窗口化寄存器文件*需要* spill/fill 机制,而这个机制根本不存在。

### 注意事项

重实现者应得到的是过程性结论,而不只是描述性结论。因为 SREG 文件是扁平且无 trap 的,超过 32 个 live value 的 SREG 压力由编译器解决,而不是由硬件解决。LSRA-v2 分配器会 spill 到保留的 SMEM 区域(`FLAGS_xla_jf_lsra_v2_reserved_smem` @ `0x223afaa8`);被 spill 的 SREG 会变成写入该区域的 `ScalarStoreSmem*`,以及之后读回的 `ScalarLoadSmem*`。load/store opcode 家族见 [SMEM 标量内存](smem-scalar-memory.md)。不存在硬件 fast-path:一次 spill 的成本是两个显式标量内存操作,编译器负责最小化它。

---

## 2. CBREG — 持有内存窗口的寄存器

### 目的

最符合"a register that windows memory" 这一*意图*的机制是 SparseCore **CBREG**(circular-buffer register)。它反转了 SPARC 思路:不是把一个内存窗口映射**寄存器名称空间,而是单个寄存器*持有*一个滑动内存窗口,并发出回绕地址流。这只是 v5+ SparseCore 特性(Viperfish `vfc`、Ghostlite `glc`、`6acc60406` `gfc`);JF/DF/PF 没有 CBREG。

### 机制

CBREG 由三个子寄存器组成:`{base, offset, size}`。它们物理上存放在三个独立硬件 bank 中,但通过 4 位 CBREG 索引作为一个寄存器寻址。所有三个 SparseCore sequencer 的 bank 名称都出现在 `.rodata` 中:

```text
SC_SCS_CBREGS_BASE   SC_SCS_CBREGS_OFFSET   SC_SCS_CBREGS_SIZE
SC_TAC_CBREGS_BASE   SC_TAC_CBREGS_OFFSET   SC_TAC_CBREGS_SIZE
SC_TEC_CBREGS_BASE   SC_TEC_CBREGS_OFFSET   SC_TEC_CBREGS_SIZE

base 是指向片上内存的窗口化指针(地址空间,即 SMEM vs TILE_SPMEM,在写入 base 时固定);size 是 offset 回绕时使用的模数;offset 是当前位置。一次访问会读取或写入 base + (offset mod size)…PostUpdate 访问变体还会在访问后推进 offset = (offset + step) mod size,即经典的 circular-buffer auto-increment。没有 modulo 指令;回绕是 OFFSET 计数器的属性,"overflow" 按设计就是回绕,从不是 trap。

驱动 CBREG 的 scalar-ALU opcode 在反编译的 emitter glue 中得到确认:

Op(符号片段)动作确认位置
SparseCoreScalarAlu_ReadCbreg将 CBREG 子字段读入 SREGscalar-ALU op set (gfc/glc/vfc)
SparseCoreScalarAlu_WriteCbreg将 SREG 写入 CBREG 子字段scalar-ALU op set
SparseCoreScalarAlu_AddCbreg给 CBREG offset 加 deltascalar-ALU op set
SparseCoreScalarAlu_MoveCbreg复制 CBREG(仅 gfc)scalar-ALU op set
SparseCoreScalarAlu_ScalarLoadCircularBufferload base+(offset mod size)isa_emitter::EmitScalarLoadOrStoreFromCb<…SparseCoreScsBundle…> @ 0x13a5e560; …TacBundle… @ 0x13a03d60
SparseCoreScalarAlu_ScalarStoreCircularBufferstore 到窗口化地址EmitScalarLoadOrStoreFromCb<…> @ 0x13a5e8e0
SparseCoreScalarAlu_ScalarLoadCircularBufferPostUpdateload,然后推进 offset(回绕)EmitScalarLoadOrStoreFromCb<…> @ 0x13a5e3a0
SparseCoreScalarAlu_ScalarStoreCircularBufferPostUpdatestore,然后推进 offset(回绕)EmitScalarLoadOrStoreFromCb<…> @ 0x13a5e720

EmitScalarLoadOrStoreFromCb 模板按 SparseCore sequencer bundle 类型实例化(SparseCoreScsBundleSparseCoreTacBundle 和 TEC bundle),因此相同的四种 circular-buffer load/store 形态会在不同地址重复出现:每个引擎一套。

面向编译器的表面

XLA 通过 LLVM intrinsic 和 MLIR dialect 驱动 CBREG,二者都以字符串/符号形式存在于二进制中:llvm.tpu.allocate.cbreg 分配一个;llvm.tpu.cbreg.add.offset[.in.place](MLIR sc_tpu.advance_cb_offset[_in_place])推进窗口;llvm.tpu.rdcbreg.offset / llvm.tpu.rdcbreg.size(MLIR tpu_rdcbreg_offset create @ 0x14734820)读取当前位置和模数。lowering 在 SparseCore pipeline emitter(§3)内部构造这些操作,使一个 tile 在一个自动递增的寄存器窗口控制下流过片上循环缓冲。

CROSS-REF — CBREG {base,size,offset} 子寄存器选择器(CbregMetadata = {0=BASE,1=SIZE,2=OFFSET})、精确的 scalar-ALU 位布局(opcode 位于 bundle bit 154;操作数 slot 位于 slot-relative bits 10/15/21),以及每个 op 的 opcode 值(Read=0x36, Write=0x35, Add=0x33, Move primary 0x00/sub 0x1b)归 CBREG 循环缓冲寄存器所有。opcode 名册位于 SCS 标量 Opcode 枚举;gather/scatter 消费者位于 Stream Gather/Scatter。本页只确定 CBREG 是持有内存窗口的寄存器,而不是寄存器上的窗口。

注意事项

重实现者必须保持方向正确。CBREG 占用一个专用硬件寄存器三元组,而不是 SREG slot;ReadCbreg/WriteCbreg 在 SREG 和 CBREG 子字段之间移动。它描述的窗口位于 SMEM 或 TILE_SPMEM 中,模数由软件设置;如果底层缓冲区太小,lowering 会报错(min_circular_buffer_byte_countcircular_buffer_size 默认 1000)。CBREG 是 SparseCore 的地址流生成器;对于 embedding datapath,它类似 NIC 的 DMA descriptor ring。


3. 流水线 OperandWindow — 可位于 SMEM 的内存子 Tile

目的

第二个同时出现 "window" 和 "SMEM" 的机制是流水线 OperandWindow:张量操作数的滑动子 tile,由编译器暂存在片上内存空间中以供流水线 kernel 使用。这是 "SMEM window" 最字面的解读:可以请求一个 OperandWindow 位于 SMEM 中;但它是缓冲区窗口,不是寄存器窗口。

机制

在 TensorCore fusion/conv 侧,窗口由 xla::jellyfish::SetWindowParams(PipelineEmitter::OperandWindow&, Shape const&, mlir::MemRefType, …) @ 0x112658a0 配置(源文件 platforms/xla/mosaic/python/mosaic_windowing_util.cc)。反编译函数从操作数的 MemRefType 读取 MLIR memory-space 属性,并映射为存储在 OperandWindow + 0x4C1+1217)处的单字节 space tag:

c
// SetWindowParams @ 0x112658a0 (decompiled, condensed)
MemorySpace = mlir::MemRefType::getMemorySpace(&memref);
attr        = (MemorySpaceAttr) MemorySpace;
Value       = attr ? mlir::tpu::MemorySpaceAttr::getValue(attr) : 0;
if      (Value == 0)  v99 = 3;        // (null attr) -> kVmem
else if (Value == 1)  v99 = 5;        //              -> kSmem
else if (Value == 6)  v99 = 13;       //              -> HOST
else                                   //              -> reject
    return xla::InvalidArgument(
        "Operand windows can only be requested in VMEM, SMEM, or HOST");
*(uint8_t *)(operand_window + 1217) = v99;   // store space tag at +0x4C1
```text

因此合法放置位置是 tag `0x3`(`kVmem`)、`0x5`(`kSmem`)和 `0xD`(HOST);任何其他 MLIR memory space 都是编译期 `absl::InvalidArgument`。同一函数中的两个相邻诊断进一步钉住了模型:`"Scalar windows not implemented."`(拒绝 scalar-shaped window)和 `"An output window does not have a memory space assigned."`(未赋值的 output window)。

第二个兄弟家族位于 SparseCore 侧:`xla::tpu::sparse_core::OperandWindow` 和 `PipelineEmitterInterface::OperandWindowDescription`,由 `FixedWindowPipelineEmitter`(FWPE)和 `VariableWindowPipelineEmitter`(VWPE)物化。它们的窗口缓冲区通常落在 SPMEM。请求窗口的 MLIR 属性是 `window_params`,由诸如 "expected %d window_params based on the number of inputs and outputs""the window shape specified in the `window_params` attribute must match the full operand shape in a persistent argument." 这样的字符串验证。

### SREG 关联(以及为什么它*不是*寄存器窗口)

`OperandWindow` 接触标量寄存器文件的唯一地方是它的*offset*:窗口的运行 offset 会物化到一个 SREG 中(`window_offset->ProducesSreg()`),然后送入标量/DMA 地址生成。这才是正确心智模型:SPU 把窗口 offset*计算*到标量寄存器中;窗口本身是内存 tile,不是寄存器。该寄存器像任何地址计算一样持有一个标量值(offset);没有任何东西在寄存器文件*之上*开窗口。

### FWPE:动态窗口大小可以存放在 SMEM

SMEM 和 "window" 还有另一种共现方式。flag `FLAGS_xla_sc_disable_fwpe_syncadds`(@ `0x223354e0`,cl::opt 名称 `xla_sc_disable_fwpe_syncadds`)带有 help string,已在 `.rodata` 中逐字确认:

> "Use TileSmem to store dynamic window sizes in fixed-window pipeline emitter instead of using sync-adds."

设置该 flag 时,FWPE 会把*动态窗口大小*存放在 TileSmem tile 中(`llvm.tpu.allocate.tilesmem` / `mlir::sparse_core::tpu_allocate_tilesmem::create` @ `0x146d7740`),而不是通过 sync-add 链重新计算。这是位于 SMEM 中的窗口*元数据*;同样没有涉及寄存器窗口,SMEM 在这里是大小值的 scratch table。

> **GOTCHA — "window in SMEM""register window."** 放置在 `kSmem` 中的 `OperandWindow`,以及缓存在 TileSmem 中的 FWPE 窗口大小,都是 *SMEM 中的数据*。二者都不会把 SMEM 的窗口映射到 SREG 名称空间中。若重实现把"operand window 可请求位于 SMEM"混同为"标量寄存器文件有 SMEM 窗口",就会建模一个不存在的寄存器分配机制。

---

## 4. 旋转 PREDICATE 寄存器 — 唯一真正的寄存器窗口

### 目的

TPU 上*确实*存在一个硬件寄存器窗口。它是唯一一个,而且它给**谓词**寄存器开窗口,不是标量寄存器,也不在 SMEM 中。它存在是因为 SparseCore 会对 embedding/scatter 循环做软件流水线,旋转谓词能在没有显式 prolog/epilog 代码的情况下实现流水线循环的 prolog/kernel/epilog。

### 机制

SparseCore SCS 和 TEC sequencer 同时带有扁平谓词 bank 和旋转谓词 bank:

```text
SC_SCS_PREGS   + SC_SCS_ROTATING_PREGS     (rotating variant present)
SC_TEC_PREGS   + SC_TEC_ROTATING_PREGS     (rotating variant present)
SC_TAC_PREGS                                (NO rotating variant)

注意 TAC sequencer 没有 SC_TAC_ROTATING_PREGS bank,这由该字符串缺失确认。旋转文件有 16 项(enum literal SPARSECORE_ROTATE_PREDICATION_PREG0_IS_1 … PREG15_IS_1),旋转由 scalar-ALU op SetRotatingPredicateRegisterHBranchRelativeRotatingPregH(字段 branch_relative_rotating_preg)驱动。

编译器通过 LLVM 后端按 generation 启用它,由 subtarget gate 控制。反编译 gate 方法没有歧义:

SubtargethasRotatingPredicates() 返回Codename
TPUGfcSubtarget (@ 0x13c62c20)16acc60406 (TPU7x)
TPUVfcSubtarget (@ 0x13c5f1e0)0Viperfish (v5)
TPUGlcSubtarget (@ 0x13c610c0)0Ghostlite (v6e)
TPUBcSubtarget (@ 0x13c59400)0BarnaCore

因此,尽管 SCS/TEC 中存在 rotating-PREG bank 名称,后端只在 gfc/6acc60406 subtarget 上启用旋转。谓词 Slot 页面记录了相同事实("Rotating predicates — 6acc60406-only — TPUGfcSubtarget::hasRotatingPredicates() = 1; all others 0")。两个 flag 控制使用和仿真:FLAGS_xla_sc_rotating_predicates(@ 0x223359d8)和 FLAGS_xla_sc_emulate_rotating_predicates(@ 0x22335978);LLVM 侧开关是 enable-rotating-predicateenable-rotating-predicate-emulation,后者描述为把 prolog 和 epilog 折叠进循环,"but not actually using rotating predicate support."

CONFIDENCE — HIGH(对原始证据的细化)。 原始发现记录了 gfc/glc 前缀的 rotating-PREG op 符号,并读到 "vfc shows the rotating-preg bank name." 反编译的 hasRotatingPredicates() gate 更精确:只有 TPUGfcSubtarget 返回 1vfcglc 和 BarnaCore subtarget 都返回 0。bank 名称可能跨 SCS/TEC 存在,但编译器只在 gfc/6acc60406 subtarget 上发出旋转。应把 bank-name presence 当作 ISA schema,把 subtarget flag 当作每代启用条件。

注意事项

这是重实现者唯一应该建模真实滑动寄存器窗口的地方,但它位于 SparseCore SCS/TEC sequencer 的谓词文件中,不在 SREG 文件中,也不在 SMEM 中。窗口位置按循环迭代前进(modulo scheduling);仿真模式会展开 prolog/epilog,而不是旋转。如果某个任务说 "TPU has a register window",这是唯一正确指代,而且它只适用于 predicate。


5. 资源分类

一张表中的分类

按 SparseCore sequencer,0.0.40 中存在的资源 bank 及其是否有窗口化变体如下:

Bank资源窗口化变体?给什么开窗口?
SC_{SCS,TAC,TEC}_SREGS标量寄存器(扁平 32 个)NO
SC_{SCS,TEC,TAC}_DREGS/VREGS数据 / 向量寄存器NO
SC_SCS_PREGS, SC_TEC_PREGS谓词寄存器YESSC_{SCS,TEC}_ROTATING_PREGSpredicate regs
SC_TAC_PREGS谓词寄存器NO
SC_{SCS,TAC,TEC}_CBREGS_{BASE,OFFSET,SIZE}circular-buffer register triple本身就是窗口tile/scalar memory
SC_{SCS,TAC,TEC}_SMEM标量内存(扁平)NO

唯一的"寄存器上的窗口"是旋转谓词文件;唯一"本身就是内存窗口的寄存器"是 CBREG 三元组;SREG 文件和 SMEM 都是扁平的。这一张表就是完整消歧。

该术语附着的三件事

"Register window" 被宽泛地用于三类不同资源,没有一个是 SREG 文件:

说法状态原因
SPU 没有 register windowTRUE扁平 32 个 SREG,5-bit 索引,LSRA spill 到 SMEM;EncodingToScalarRegister 限制 idx ≤ 0x1F
SMEM 没有 register-window 机制TRUE扁平 byte/word 内存;触及 SMEM 的窗口是 CBREG memory-window 和 OperandWindow buffer placement,二者都不给寄存器开窗口
MXU gain 像 stationary weight "window" 一样工作TRUE as metaphorGainLatchModeProto 把权重 latch 到 systolic array;二进制没有使用 任何 "window" 术语;与 SMEM 和 SPU 无关

为完整性,MXU "GainLatch register window" 值得用一句话说明:weight-stationary gain register 只是在描述上被称为 "window"。二进制把它们命名为 GainLatchModeProtoGAIN_LATCH_MODE_NONE / _NO_XPOSE_* / _XPOSE_* / _PACKED_* …),从不使用 "window"。这些 gain 是 MXU 内部寄存器集,会在多个 matmul 期间 stationary latch;功能上可称作权重的 "window",但与 SPU SREG 文件和 SMEM 无关。它不得与 SMEM/SREG 问题混同。

确定答案

不存在窗口化或旋转标量寄存器文件意义上的 SMEM register-window,也不存在映射在 SMEM 之上的 register-window。SREG 文件是一个扁平、受硬件边界限制的 32 项文件,通过软件(LSRA-v2)spill 到 SMEM。该短语至多指向:CBREG(持有 {base,offset,size} 内存窗口的寄存器,最贴切)、流水线 OperandWindow(可能暂存在 SMEM 的内存子 tile),或旋转 PREDICATE 文件(唯一真正的硬件寄存器窗口,仅 predicate,仅在 gfc/6acc60406 subtarget 上启用)。重实现应把三者建模为不同机制,并保持 SREG 文件扁平。


交叉引用