定位 inner_ms 的 3.3 倍:是争抢不是算法档,撤回 22/86 拆分

服务端跑 probe_inner.py 与本机对表:分档占比一致(TF_DF 两腿 68~74%,
信号链 16~21ms),此前报的「chan 构建 22ms / 信号链 86ms」是无效减法
——孤立环境的 1m append 减在场十币的 inner_ms,还漏了 5m 腿。

真实构成:inner_ms 100ms = 约 30ms 计算 × 3.3 倍争抢。逐个排除
_rebuild(1.6ms)、币种差异、周期重建(21.5%/1.5x)、批内次序(相关-0.083)
后,用外生的到达密集度确认(67→117ms),并以注入合成负载复现
(2 个满载进程 2.68x,3 个 2.86x,在场实测 2.24~3.34x)。

心跳判定不再推荐「继续压算法」,改为加核或减币。

第一版用 t_signal-inner_ms 反推并发区间得相关 0.533,是循环构造,
已废弃并在 §5.72 记下这个坑。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jack
2026-08-28 16:19:25 +08:00
co-authored by Cursor
parent be442783a1
commit cef894376c
2 changed files with 81 additions and 8 deletions
+71 -3
View File
@@ -1581,9 +1581,14 @@ python step46_engine_parity.py --check --rows 200000 --out step46_baseline_big.j
**十币 / 2 核的效果:** 清空 560→247ms,排队 92→10ms,纯计算 219→108ms
内存 597→598MiB(20 条缓存流的开销在噪声里)。
**瓶颈已经换位置了:** `inner_ms` 108ms 里 chan 构建只占约 22ms,其余 86ms
`build_htf_zones` / `find_fast_bsp3` / `attach_htf_context`。再压 chan
构建收益有限,要继续压得看下游那三个。
~~**瓶颈已经换位置了:** `inner_ms` 108ms 里 chan 构建只占约 22ms,其余 86ms
是 `build_htf_zones` / `find_fast_bsp3` / `attach_htf_context`。~~
⚠️ **上面这段是错的,2026-08-28 撤回,见 §5.72。** 那个 86ms 不是测出来的,
是减出来的:22ms 是孤立环境下 1m 腿的 `append_bar`108ms 是跑着的十币采集器
里的 `inner_ms`。一个无争抢一个有争抢,还漏了 5m 腿,这个减法不成立。
实测信号链合计只有 16~21ms`build_htf_zones` 是其中最大的一项(13ms),
`find_fast_bsp3` / attach 合计不到 2%。
#### 5.71 第二轮引擎优化(2026-08-28,服务端反馈驱动)
@@ -1635,6 +1640,69 @@ EMA/MACD/ATR 是递推的、BB/SMA/量比是窗口的,理论上都能 O(1) 更
**曾怀疑是 payload 反序列化,实测 `_rebuild` 只有 1.0ms,假设不成立。**
两边跑同一个探针对分档表,才能定位那 86ms。
**→ 已定位,见 §5.72:那 86ms 不存在,是服务端的减法错了。分档两边一致。**
#### 5.72 那 86ms 不存在:`inner_ms` 的 3.3 倍是争抢,不是某个算法档
服务端跑了同一个 `probe_inner.py`(2 核,采集器十币在跑)。**分档占比两边
对得上,四倍差距是伪命题:**
| | 本机 | 服务端 |
|---|---|---|
| `TF_DF` 两条腿 | 70% | **68~74%** |
| `build_htf_zones` | 13% | 10~12% |
| `htf_fx_timeline` | 6% | 5% |
| `find_fast_bsp3`+ladder+attach | <2% | **<2%** |
| 信号链合计 | — | **16~21ms**(不是 86ms |
服务端那个 22/86 是无效减法(见 §5.7 的撤回批注)。
**但对完表冒出一个真问题:** 探针里全量 `TF_DF` 合计 106~126ms,而采集器走
增量报的 `inner_ms` 也是 100ms 中位——增量该快得多,两个数却一样。差额去哪了?
排查顺序与结论:
| 假设 | 实测 | 判定 |
|---|---|---|
| `_rebuild` 反序列化贵 | 两腿合计 **1.6ms** | ✗ |
| 某些币结构复杂 | 十币中位 92~105ms,几乎一致 | ✗ |
| 周期性全量重建拉高中位 | 占 21.5%,且只贵 1.5x133 vs 91ms | 部分 |
| 批内后段被拖慢 | `inner_ms` 对批内次序相关 **0.083**,是平的 | ✗ |
| **CPU 争抢** | 见下 | **✓ 主因** |
「批内平坦」一度被我读成争抢的反证,其实反了:**两个 worker 在整段突发期都
满载时,批内每个币被拖慢的程度一样,平坦正是均匀争抢的表现。**
用外生指标(到达密集度,仅由 `t_data_ms` 决定,不含 `inner_ms`):
| ±250ms 内到达币数 | 1 | 2 | 4 | 6 | 8 |
|---|---|---|---|---|---|
| `inner_ms` 中位 | 67ms | 80ms | 94ms | 105ms | 117ms |
⚠️ **第一版用 `beg = t_signal_ms inner_ms` 反推并发区间,得到相关 0.533,
这个数是废的**——`inner_ms` 越大区间越宽、重叠自然越多,相关性有一部分是构造
出来的。换外生指标后相关降到 0.271。**凡是用被解释变量去构造解释变量的,先
怀疑循环。**
注入合成负载复现(离线同一窗口,2 核):
| 背景 | `compute` 增量 | 放大 |
|---|---|---|
| 空闲 | **29.9ms** | 1.00x |
| 1 个满载进程 | 41.7ms | 1.39x |
| 2 个满载进程 | 80.2ms | 2.68x |
| 3 个满载进程 | 85.4ms | 2.86x |
采集器实测:密集度=1 时 67ms(2.24x)、总体中位 100ms3.34x)。落在「1~2 个
满载进程」到「2 个以上」之间,正是 **2 核上跑 主进程 + 2 worker** 该有的样子
(主进程常驻负载不小:10 路 K 线 WS + 10 路盘口 + 10Hz 采样)。
**结论与代价:** `inner_ms` 100ms = **约 30ms 真实计算 × 3.3 倍争抢**
剩下的延迟不是算法性质的,继续压引擎收益有限(把 30ms 砍一半只换回 15ms×3.3
≈ 50ms,且越往下越难)。真正的杠杆是**核数**或**减币**。
⚠️ 这和 §5.7 心跳里「币数 > 核数时加 worker 无用」不矛盾但要分清:**加 worker
确实无用(worker 已等于核数),加核有用。** 两者在原判定里被混成一句了。
---
## 6. 接下来要做的事(按优先级)