0.10.0:row-wise fusion(同 deps 行内融合)¶
适用读者
- 关心 0.10.0 宽表薄
call_by/compute_expr吞吐的使用方 - 需要讲清「何时融合 / 何时回退 / 与 write-precompute 如何分工」的维护者
- 想看前后对拍数字与图的同学
版本锚定:Scalim 0.10.0。
同一 compute 段内、依赖集合完全相同的派生字段,引擎默认改为 按行读一次 deps → 依次算组内字段——零新 YAML、无总开关。
不减少 calculator 调用次数(仍为 N×M);减的是重复取依赖与字段循环框架税。
| 契约 | 0.10.0 行为 |
|---|---|
| Authoring | 不变 |
| 输出值 | 与 field-major 一致(golden_ok) |
| Calculator 调用次数 | 仍为每字段每行一次(calc_calls == N×M) |
| 列 sink | 不融合(安全外壳) |
观测订阅 FIELD_COMPUTE / OPERATOR_SPAN |
不融合 |
EXP call_by memo 命中组内字段 |
整组不融合 |
架构:arch.md §5.4。
版本亮点总览:0.10.0 重点特性。
0.10.0 重点特性 · 版本总览(折叠)
单一事实来源为独立章节 0.10.0 重点特性,此处折普览。
姊妹能力(写出前晚算):write-precompute-0.10。
姊妹能力(同 LoadRef 分片并行):lookup-chunk-parallel-0.10。
测量摘要日期:。
数据:assets/data/rowwise-fusion-0.10.json。¶
1. 一图看懂:field-major vs row-wise¶
flowchart LR
subgraph major["field-major(对照 / 外壳外)"]
M1[for field in group] --> M2[for row: 读 deps]
M2 --> M3[calc / store]
end
subgraph fused["0.10 row-wise fusion"]
F1[for row: 读 deps 一次] --> F2[for field in group]
F2 --> F3[calc / store]
end
major -.->|同一签名 · 同一黄金值<br/>calc_calls 仍 N×M| fused
flowchart TD
C[compute 段候选字段] --> Q1{同段 + deps 完全相同?}
Q1 -->|否| FM[field-major]
Q1 -->|是| Q2{无 $ctx / 非常量 / 互不依赖?}
Q2 -->|否| FM
Q2 -->|是| Q3{安全外壳允许?}
Q3 -->|列 sink / 订阅事件 / memo / 启用 fast_fail| FM
Q3 -->|是| Fuse[row-wise 融合]
与 write-precompute(c10)的分工¶
| write-precompute | row-wise fusion | |
|---|---|---|
| 作用对象 | 只写出、无下游消费者的 late_fields |
仍在 Compute 段 的同 deps 组 |
| 主收益 | 少扛中间驻留 + 行路径墙钟 | 少重复读 deps / 调度税 |
| 调用次数 | 不变 | 不变 |
| 同字段会不会「双重优化」 | late 在 compute 被跳过 → 不会再进 fusion | 只融 early 字段 |
本页证据为隔离 c20:清空 late_fields 后对拍(否则 write-only 派生会走 c10 晚算路径)。
2. 实际例子:前后对拍¶
合成计数 shape:薄 call_by、共享 (v0, v1)、内存 sink、全表黄金;同一 plan 仅切 compute_fusion_groups(空 = field-major)。
2.1 加速比(D3)¶
宽表行路径约 1.02×–1.17×(Python 3.6.15);列路径接近 1.0×(外壳关闭,噪声带)。
2.2 行路径墙钟:field-major vs fused(D3)¶
2.3 明细表(对拍)¶
测量环境:Python 3.6.15,runs=1。数据:assets/data/rowwise-fusion-0.10.json。
| Shape | N / M / sink | field-major (s) | fused (s) | 加速 | 组数 | 黄金 / calc_calls |
|---|---|---|---|---|---|---|
| 宽表同 deps·行 | 10k / 80 / row | 1.705 | 1.455 | 1.17× | 1 | ✓ / 相等 |
| 报表宽派生·行 | 20k / 48 / row | 2.205 | 1.927 | 1.14× | 1 | ✓ / 相等 |
| 大行数中等宽·行 | 50k / 32 / row | 4.086 | 3.549 | 1.15× | 1 | ✓ / 相等 |
| 引擎代理宽表·行 | 8k / 120 / row | 1.962 | 1.676 | 1.17× | 1 | ✓ / 相等 |
| 宽表同 deps·列 | 10k / 80 / column | 1.242 | 1.204 | 1.03× | 1* | ✓ / 相等 |
| 窄表同 deps·行 | 40k / 4 / row | 1.093 | 1.074 | 1.02× | 1 | ✓ / 相等 |
*列路径计划期仍能识别组,但运行时安全外壳禁用融合;墙钟接近噪声。
读法
- 「更快」= 少重复读 deps / 少字段级循环税,不是少算业务函数。
M越大、deps 完全相同的簇越宽,行路径收益越明显。- 所有 case:
golden_ok+calc_calls == N×M两边相等。
3. 迷你 walkthrough(教学)¶
2 行 × 3 个同 deps 薄 call_by:
| 依赖读取次数 | calculator 调用 | |
|---|---|---|
| field-major | ≈ 12(N×M×D,D=2) | 6 |
| row-wise | ≈ 4(N×D) | 6(不变) |
引擎 MVP 复现:
uv run python llmanspec/changes/archive/2026-08-02-c20-compute-expr-rowwise-fusion/mvp/repro_nxm_framework_tax.py \
--rows 4000 --wide-fields 40 --runs 3
本页同款 workload(仓库根目录运行):
uv run python docs/doc/releases/repro/c20-workload-shapes/run_ab.py --runs 3
# Python 3.6:
PYTHONPATH=src .tmp/venvs/py36-scalim/bin/python \
docs/doc/releases/repro/c20-workload-shapes/run_ab.py --runs 1
复现脚本(已入库):docs/doc/releases/repro/c20-workload-shapes/run_ab.py。
4. 谁受益 / 谁不变¶
flowchart TD
Start[你的 demand] --> A{大量同 deps 薄派生仍在 Compute?}
A -->|是,行写出| Win[高概率:~1.1×–1.3× 量级]
A -->|是,但列写出| SameCol[外壳关闭 ≈ 不变]
A -->|否:互相依赖 / deps 不全等| Same[不进同一 fusion group]
Start --> B{字段已是 late_fields?}
B -->|是| C10[走 write-precompute;本能力不双重融合]
5. GitHub Release 引用¶
## Highlights
- row-wise fusion(默认):同 deps 派生字段按行融合,减 N×M 框架税;calc_calls 不变。
详述与对拍:docs/doc/releases/rowwise-fusion-0.10.md
- write-precompute:docs/doc/releases/write-precompute-0.10.md
6. 相关链接¶
- Spec:
llmanspec/specs/execution-compute-rowwise-fusion/ - 归档 change:
llmanspec/changes/archive/2026-08-02-c20-compute-expr-rowwise-fusion/ - 大形状 RSS(≤10%):
.tmp/evidence/c20-rowwise-fusion-rss/(可再生成,不入库) - 复现脚本(已入库):
docs/doc/releases/repro/c20-workload-shapes/run_ab.py