动机
当前一条 int64·add 在主循环最坏要几百次 strcmp + 一次 kvspace 往返:op_is_control(≤4) → IsNative(strip_num_kind + myrwircaps 线性 ~100) → Native(再扫一遍 ~100) → isothersrwir(kvspace 读) → 算子内读两操作数 head langtype 字符串归约。瓶颈是「处处字符串」。本 issue 把一条 rwir 指令与其参数在 decode 期一次性 id 化,运行期纯跳表 + 指针 + 整数 tag,消除热路径全部字符串匹配。
设计模型:三表 = 三正交维的 runtime 私有 id 化
head 是 ref × storetype × langtype(见三正交维 head 模型)。runtime 把每一维投影成本进程私有的整数:
| 维 |
kvspace 事实(跨 runtime 唯一契约) |
runtime 内部表(私有) |
表形态 |
| opcode(动作) |
opcode 字符串 |
rwirtable |
native 稀疏登记 + user/extern 归一 |
| ref |
wire 字节 |
(enum,免表) |
INLINE/PTR/EXT 常量 |
| storetype(物理布局) |
wire 字节 |
storetypetable |
闭集 → 静态数组 |
| langtype(语义类型) |
kindexpr 串 |
langtypetable |
开集 → 运行期 intern |
不变量 IV-0(runtime-local id)
rwirtable / storetypetable / langtypetable 及 decode-once 缓存均为单 runtime 进程私有。其 id 不写入 kvspace、不经 handoff/vthread/网络传递、不与同机他进程共享。其它 runtime 不认这些 id;跨 runtime 的唯一契约是 kvspace 的 opcode 字符串、langtype kindexpr 串、storetype 字节。runtime-c 把 "add" intern 成 id=5、runtime-rs intern 成 id=7,二者读同一条 kvspace 指令、各跑各的表、互不知情。
两层彻底分离:数据模型/wire 层(ref×storetype×langtype)跨 runtime 一致,是唯一契约;runtime 层三张表是对这三维的私有 id 化。
精度前缀保留(推翻早期「删 specialize」的方向)
C/C++ 原生算术只覆盖 int8..int64 + fp32/fp64。int4、fp8(E4M3/E5M2)、bf16、int2/int1 这些量化/混精类型,C 的 + 表达不了,各需专门实现体(打包/解包、饱和、软件模拟)。所以 int64·add/fp8·add/int4·add 本就是不同实现体,前缀 {langtype}·{op} 是选实现体的键。
- specialize 保留(数值算子精度前缀 = 选实现体,非冗余)。
- 废 strip_num_kind——它把精度从 opcode 抹掉、逼所有精度挤进一个 C 原生
kvlangBuiltinAdd,正是 int4/fp8 支持不了的病根。
rwirtable key = 完整 {langtype}·{op}(方案 A)
lookup 语义(两级,稀疏 intern):
- 先查完整 opcode(命中 = 有专精实现,如
fp8·add → 专用 fn);
- 未命中则拆末段前缀查裸算子(命中 = C 原生通用实现,如
int64·add → kvlangBuiltinAdd,精度经内置 langtype_id 传入,不重读 head);
- 两级都 miss → 非本 runtime native → 按精度粒度 handoff 给实现它的扩展 runtime(如 gpu-compute 的
fp8·matmul)。
前缀白拿两个好处:能力边界按精度表达(runtime 可声明「有 int64·add,没 fp8·add」→ 后者自动 handoff);稀疏登记(不是 ops×精度 稠密笛卡尔积,实现了哪个登记哪个,扩展 runtime 只登记自己的组合)。与「融合归扩展编译器」不矛盾:选实现体(前缀→精度 fn)核心 runtime 做;算子融合(多条合成 fused kernel)归扩展编译器。
一条指令全 id 化后的形态
kvspace 事实(不变): [addr0,0]="int64·add" reads: head.langtype="int64", storetype=ATOM
decode 一次后(进程内缓存,永不失效):
op_id = rwirtable("int64·add") // 完整 opcode intern
reads[i] = { ptr, ref, storetype_id=ATOM, langtype_id=INT64 } // ref=0 → 0copy 指针
运行期: caps[op_id].fn(&f) // 统一跳表,零分支
运行期全程: 零字符串、零 kvspace 重读、零拷贝
三条不可变性(地基)
- 指令 XValue layout 后冻结(runtime 只读指令、只读写数据槽)→ decoded 缓存永不失效。
- 只 decode 一次:进程内按指令坐标缓存
{op_id, params[]};循环体重复执行命中缓存。崩溃重启缓存重建、PC 仍从 kvspace 恢复。
- 0copy 仅读参:读参(ref=0)以 kvspace 借用指针零拷贝喂 fn,生命周期 = 单指令执行期;写参照旧走
WriteInPlace/NewPlace,不 0copy。
P0 裁决:固化 + 整数 guard
decode 期固化 langtype_id,执行时 cached_id == slot_id 整数 guard——静态类型场景恒相等(零感知成本),动态换型则 re-intern 更新。不必现在把 kvlang 类型语义钉死为纯静态,又拿到静态全部性能。
子任务
边界(不做)
不改 wire、不改 kvspace 唯一事实、id 不持久化、写参不 0copy、不引入编译期类型选核与融合(归扩展编译器)。
依赖
保留 specialize(撤销 #202 中「剥离 specialize」一条);本 issue 废 strip_num_kind。
动机
当前一条
int64·add在主循环最坏要几百次strcmp+ 一次 kvspace 往返:op_is_control(≤4) →IsNative(strip_num_kind+myrwircaps线性 ~100) →Native(再扫一遍 ~100) →isothersrwir(kvspace 读) → 算子内读两操作数 head langtype 字符串归约。瓶颈是「处处字符串」。本 issue 把一条 rwir 指令与其参数在 decode 期一次性 id 化,运行期纯跳表 + 指针 + 整数 tag,消除热路径全部字符串匹配。设计模型:三表 = 三正交维的 runtime 私有 id 化
head 是
ref × storetype × langtype(见三正交维 head 模型)。runtime 把每一维投影成本进程私有的整数:不变量 IV-0(runtime-local id)
两层彻底分离:数据模型/wire 层(
ref×storetype×langtype)跨 runtime 一致,是唯一契约;runtime 层三张表是对这三维的私有 id 化。精度前缀保留(推翻早期「删 specialize」的方向)
C/C++ 原生算术只覆盖 int8..int64 + fp32/fp64。int4、fp8(E4M3/E5M2)、bf16、int2/int1 这些量化/混精类型,C 的
+表达不了,各需专门实现体(打包/解包、饱和、软件模拟)。所以int64·add/fp8·add/int4·add本就是不同实现体,前缀{langtype}·{op}是选实现体的键。kvlangBuiltinAdd,正是 int4/fp8 支持不了的病根。rwirtable key = 完整
{langtype}·{op}(方案 A)lookup 语义(两级,稀疏 intern):
fp8·add→ 专用 fn);int64·add→kvlangBuiltinAdd,精度经内置 langtype_id 传入,不重读 head);fp8·matmul)。前缀白拿两个好处:能力边界按精度表达(runtime 可声明「有 int64·add,没 fp8·add」→ 后者自动 handoff);稀疏登记(不是 ops×精度 稠密笛卡尔积,实现了哪个登记哪个,扩展 runtime 只登记自己的组合)。与「融合归扩展编译器」不矛盾:选实现体(前缀→精度 fn)核心 runtime 做;算子融合(多条合成 fused kernel)归扩展编译器。
一条指令全 id 化后的形态
三条不可变性(地基)
{op_id, params[]};循环体重复执行命中缓存。崩溃重启缓存重建、PC 仍从 kvspace 恢复。WriteInPlace/NewPlace,不 0copy。P0 裁决:固化 + 整数 guard
decode 期固化
langtype_id,执行时cached_id == slot_id整数 guard——静态类型场景恒相等(零感知成本),动态换型则 re-intern 更新。不必现在把 kvlang 类型语义钉死为纯静态,又拿到静态全部性能。子任务
kvlangRwirInst_t加op_id;kvlangParam_t加{ref, storetype_id, langtype_id, ptr};建 rwirtable(完整 opcode → id,两级 lookup)、langtypetable(intern)、storetype 静态表;废 strip_num_kind;decode-once 进程内缓存(按指令坐标);主循环改caps[op_id].fn;读参 0copy 指针;热点算子按 op_id/langtype_id 直选实现体。边界(不做)
不改 wire、不改 kvspace 唯一事实、id 不持久化、写参不 0copy、不引入编译期类型选核与融合(归扩展编译器)。
依赖
保留 specialize(撤销 #202 中「剥离 specialize」一条);本 issue 废 strip_num_kind。