Phase 5: freeze E5-4 malloc tiny direct (neutral)
This commit is contained in:
@ -2,10 +2,11 @@
|
||||
|
||||
## Executive Summary
|
||||
|
||||
**Recommendation**: **DEFER E5-3 optimization**. Continue with established winning patterns (E5-1 style wrapper-level optimizations) rather than pursuing diminishing-returns micro-optimizations in profiler hot spots.
|
||||
**Recommendation**: **DEFER E5-3 candidates** and move to **E6 (ENV snapshot branch-shape fix)**.
|
||||
|
||||
**Rationale**:
|
||||
- E5-2 (Header Write-Once, 3.35% self%) achieved only +0.45% NEUTRAL
|
||||
- E5-4 (Malloc Tiny Direct, E5-1 pattern) also came back NEUTRAL (-0.48%)
|
||||
- E5-3 candidates (7.14%, 3.39%, 2.97% self%) have similar or worse ROI profiles
|
||||
- Profiler self% != optimization opportunity (time-weighted samples can mislead)
|
||||
- Cumulative gains from E4+E5-1 (~+9-10%) represent significant progress
|
||||
@ -125,17 +126,19 @@
|
||||
- **Method**: Single header check → direct call to free_tiny_fast()
|
||||
- **Result**: +3.35% (GO)
|
||||
|
||||
**Replicable Patterns**:
|
||||
1. **Malloc Tiny Direct**: Apply E5-1 pattern to malloc() side
|
||||
- Single size check → direct call to malloc_tiny_fast_for_class()
|
||||
- Eliminate: Size validation redundancy, ENV snapshot overhead
|
||||
- Expected: +2-4% (similar to E5-1)
|
||||
**Replicable Patterns** (updated):
|
||||
1. **Malloc Tiny Direct (E5-4)**: Tested → ⚪ NEUTRAL(-0.48%)→ freeze
|
||||
- Lesson: alloc side is already thin (LTO/inlining), so wrapper-level direct bypass doesn't remove real work
|
||||
|
||||
2. **Alloc Gate Specialization**: Per-class fast paths
|
||||
- C0-C3: Direct to LEGACY (skip policy snapshot)
|
||||
- C4-C7: Route-specific fast paths
|
||||
- Expected: +1-3%
|
||||
|
||||
3. **E6: ENV snapshot branch-shape fix**
|
||||
- Semantics unchanged, only branch shape for MIXED where `HAKMEM_ENV_SNAPSHOT=1` is steady-state
|
||||
- Goal: reduce mispredicts from “OFF 前提” hints
|
||||
|
||||
### Priority 2: Profile New Baseline
|
||||
|
||||
After E4+E5-1 adoption (~+9-10% cumulative):
|
||||
|
||||
228
docs/analysis/PHASE5_E5_4_MALLOC_TINY_DIRECT_AB_TEST_RESULTS.md
Normal file
228
docs/analysis/PHASE5_E5_4_MALLOC_TINY_DIRECT_AB_TEST_RESULTS.md
Normal file
@ -0,0 +1,228 @@
|
||||
# Phase 5 E5-4: Malloc Tiny Direct Path A/B Test Results
|
||||
|
||||
## 概要
|
||||
|
||||
**実施日**: 2025-12-14
|
||||
**Phase**: Phase 5 E5-4
|
||||
**目的**: E5-1(Free Tiny Direct +3.35%)の成功パターンを malloc 側に適用
|
||||
**仮説**: `malloc()` wrapper から `tiny_alloc_gate_fast()` の "ゲート税" を削り、`malloc_tiny_fast_for_class()` へ最短で入る
|
||||
|
||||
## 実装内容
|
||||
|
||||
### 新規 Box
|
||||
|
||||
1. **ENV gate**: `core/box/malloc_tiny_direct_env_box.h`
|
||||
- ENV: `HAKMEM_MALLOC_TINY_DIRECT=0/1` (default: 0)
|
||||
- Lazy init、atomic cache
|
||||
|
||||
2. **Stats box**: `core/box/malloc_tiny_direct_stats_box.h`
|
||||
- カウンタ: `direct_total`, `direct_hit`, `fast_null`, `class_oob`
|
||||
- `HAKMEM_DEBUG_COUNTERS=0` で compile-out
|
||||
|
||||
### Wrapper 統合
|
||||
|
||||
- 統合箇所: `core/box/hak_wrappers.inc.h` の `malloc()` wrapper
|
||||
- E4-2 snapshot 内、`tiny_alloc_gate_fast()` 呼び出しの**前**に直接パスを追加
|
||||
|
||||
**Direct path 条件**:
|
||||
- `malloc_wrapper_env_snapshot_enabled()` が ON
|
||||
- `env->front_gate_unified` が true
|
||||
- `env->tiny_max_size_256 && size <= 256`
|
||||
- `class_idx = hak_tiny_size_to_class(size)` が [0..7]
|
||||
|
||||
**Direct path 呼び出し**:
|
||||
```c
|
||||
void* ptr = malloc_tiny_fast_for_class(size, class_idx);
|
||||
if (ptr != NULL) {
|
||||
return ptr; // Success
|
||||
}
|
||||
// Fall through to normal path (refill failure)
|
||||
```
|
||||
|
||||
## A/B テスト結果 (MIXED_TINYV3_C7_SAFE)
|
||||
|
||||
### 環境
|
||||
- ベンチマーク: `bench_random_mixed_hakmem 20000000 400 1`
|
||||
- プロファイル: `HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE`
|
||||
- 実行回数: 各 10 runs
|
||||
|
||||
### Baseline (E5-4 OFF)
|
||||
```
|
||||
HAKMEM_MALLOC_TINY_DIRECT=0
|
||||
```
|
||||
|
||||
| Run | Throughput (ops/s) |
|
||||
|-----|-------------------:|
|
||||
| 1 | 44,632,327 |
|
||||
| 2 | 45,056,063 |
|
||||
| 3 | 44,844,339 |
|
||||
| 4 | 43,846,790 |
|
||||
| 5 | 43,997,456 |
|
||||
| 6 | 44,610,819 |
|
||||
| 7 | 44,663,596 |
|
||||
| 8 | 44,817,886 |
|
||||
| 9 | 44,768,872 |
|
||||
| 10 | 44,249,556 |
|
||||
|
||||
**Mean**: 44,548,770 ops/s
|
||||
**Std**: 390,988
|
||||
|
||||
### Optimized (E5-4 ON)
|
||||
```
|
||||
HAKMEM_MALLOC_TINY_DIRECT=1
|
||||
```
|
||||
|
||||
| Run | Throughput (ops/s) |
|
||||
|-----|-------------------:|
|
||||
| 1 | 44,324,303 |
|
||||
| 2 | 44,816,668 |
|
||||
| 3 | 44,990,916 |
|
||||
| 4 | 43,969,704 |
|
||||
| 5 | 44,419,400 |
|
||||
| 6 | 43,661,260 |
|
||||
| 7 | 44,678,785 |
|
||||
| 8 | 44,415,232 |
|
||||
| 9 | 43,379,834 |
|
||||
| 10 | 44,708,462 |
|
||||
|
||||
**Mean**: 44,336,456 ops/s
|
||||
**Std**: 519,963
|
||||
|
||||
### 統計分析
|
||||
|
||||
```
|
||||
Delta: -212,314 ops/s (-0.48%)
|
||||
```
|
||||
|
||||
**判定**: **NEUTRAL** (±1.0% 以内)
|
||||
|
||||
- GO 基準: +1.0% 以上
|
||||
- NEUTRAL: ±1.0% 以内
|
||||
- NO-GO: -1.0% 以下
|
||||
|
||||
## 健康診断
|
||||
|
||||
```
|
||||
scripts/verify_health_profiles.sh
|
||||
```
|
||||
|
||||
**結果**: ✅ OK
|
||||
|
||||
- MIXED_TINYV3_C7_SAFE: 38.5M ops/s
|
||||
- C6_HEAVY_LEGACY_POOLV1: 22.9M ops/s
|
||||
|
||||
## perf Analysis (Baseline)
|
||||
|
||||
**tiny_alloc_gate_fast self%**: 20.04% (Step 0 測定)
|
||||
|
||||
→ ROI は高いはずだったが、直接パスの効果は見られず
|
||||
|
||||
## 考察
|
||||
|
||||
### なぜ E5-1 (Free) は成功し、E5-4 (Malloc) は失敗したのか?
|
||||
|
||||
#### E5-1 (Free Tiny Direct) の成功要因
|
||||
- Free 側: `free_tiny_fast()` への直接パスで、header 読み取り (1 load) → 即座に free 完了
|
||||
- Gate overhead が顕著だった(複数の条件分岐 + TLS アクセス)
|
||||
|
||||
#### E5-4 (Malloc Tiny Direct) が効果なかった理由
|
||||
|
||||
1. **既存パスが十分に最適化されている**
|
||||
- `tiny_alloc_gate_fast()` → `malloc_tiny_fast_for_class()` は既に薄い wrapper
|
||||
- Gate 自体のオーバーヘッドが Free 側ほど大きくない
|
||||
|
||||
2. **直接パスの追加条件チェックがコストになった**
|
||||
- `malloc_tiny_direct_enabled()` 判定
|
||||
- `class_idx` 範囲チェック
|
||||
- これらが既存の最適化を打ち消した可能性
|
||||
|
||||
3. **malloc 側の本当の hotspot は別の場所**
|
||||
- perf では `tiny_alloc_gate_fast` が 20% だったが、その内訳は:
|
||||
- TLS アクセス (`g_tls_sll`)
|
||||
- Refill ロジック
|
||||
- Header 書き込み
|
||||
- Gate 自体の "税" は小さかった可能性
|
||||
|
||||
4. **Compiler の最適化がすでに inlining している**
|
||||
- LTO + -O3 により、`tiny_alloc_gate_fast()` 内の `malloc_tiny_fast_for_class()` 呼び出しが inline 済み
|
||||
- 直接パスを追加しても、実質的な差がない
|
||||
|
||||
### E5-1 との対比
|
||||
|
||||
| 項目 | E5-1 (Free) | E5-4 (Malloc) |
|
||||
|------|------------|--------------|
|
||||
| 結果 | +3.35% (GO) | -0.48% (NEUTRAL) |
|
||||
| Gate overhead | 大(多段階条件分岐) | 小(薄い wrapper) |
|
||||
| Direct path 効果 | 顕著(header 1 load で即完了) | なし(既に最適化済み) |
|
||||
| Hotspot | Gate 自体が重い | TLS/Refill が重い |
|
||||
|
||||
## 結論
|
||||
|
||||
**Phase 5 E5-4: NEUTRAL → FREEZE**
|
||||
|
||||
- A/B テスト結果: **-0.48%** (NEUTRAL)
|
||||
- 健康診断: ✅ OK
|
||||
- 判定: **FREEZE**(昇格しない、ENV gate default OFF のまま)
|
||||
|
||||
E5-1 の成功パターンは、**Free 側特有の条件**(Gate overhead の大きさ、header 検証の単純さ)によるものであり、Malloc 側には適用できなかった。
|
||||
|
||||
## Rollback
|
||||
|
||||
ENV gate が default OFF なので、追加コストなし。
|
||||
|
||||
削除する場合:
|
||||
1. `core/box/malloc_tiny_direct_env_box.h` を削除
|
||||
2. `core/box/malloc_tiny_direct_stats_box.h` を削除
|
||||
3. `core/box/hak_wrappers.inc.h` の E5-4 統合部分を削除
|
||||
|
||||
## 次のステップ
|
||||
|
||||
E5-4 は FREEZE し、次の候補へ:
|
||||
|
||||
- **E5-5**: Malloc 側の本当の hotspot(TLS アクセス削減、Refill 最適化)に注目
|
||||
- **E6**: 別の最適化軸(例: C6 ULTRA-alloc の範囲拡大、MID v3 の改善)
|
||||
|
||||
## 付録: コード差分
|
||||
|
||||
### malloc_tiny_direct_env_box.h
|
||||
```c
|
||||
// Phase 5 E5-4: Malloc Tiny Direct Path - ENV Gate Box
|
||||
// ENV: HAKMEM_MALLOC_TINY_DIRECT=0/1 (default: 0)
|
||||
static inline int malloc_tiny_direct_enabled(void) {
|
||||
static _Atomic int cached = -1;
|
||||
int val = atomic_load_explicit(&cached, memory_order_relaxed);
|
||||
if (__builtin_expect(val == -1, 0)) {
|
||||
const char* env = getenv("HAKMEM_MALLOC_TINY_DIRECT");
|
||||
int enabled = (env && env[0] != '0' && env[0] != '\0') ? 1 : 0;
|
||||
atomic_store_explicit(&cached, enabled, memory_order_relaxed);
|
||||
val = enabled;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
```
|
||||
|
||||
### hak_wrappers.inc.h (統合箇所)
|
||||
```c
|
||||
// Phase 5 E5-4: Malloc Tiny Direct Path (ENV-gated, opt-in)
|
||||
if (__builtin_expect(malloc_tiny_direct_enabled(), 0)) {
|
||||
if (__builtin_expect(env->front_gate_unified && env->tiny_max_size_256 && size <= 256, 1)) {
|
||||
MALLOC_TINY_DIRECT_STAT_INC(direct_total);
|
||||
int class_idx = hak_tiny_size_to_class(size);
|
||||
if (__builtin_expect(class_idx >= 0 && class_idx < 8, 1)) {
|
||||
void* ptr = malloc_tiny_fast_for_class(size, class_idx);
|
||||
if (__builtin_expect(ptr != NULL, 1)) {
|
||||
MALLOC_TINY_DIRECT_STAT_INC(direct_hit);
|
||||
return ptr;
|
||||
}
|
||||
MALLOC_TINY_DIRECT_STAT_INC(fast_null);
|
||||
} else {
|
||||
MALLOC_TINY_DIRECT_STAT_INC(class_oob);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**実施者**: Claude Code (Sonnet 4.5)
|
||||
**日付**: 2025-12-14
|
||||
@ -1,15 +1,15 @@
|
||||
# Phase 5 E5-4: Malloc Tiny Direct Path(次の指示書)
|
||||
# Phase 5 E5-4: Malloc Tiny Direct Path(次の指示書 / 結果)
|
||||
|
||||
## Status(2025-12-14 / E5-2 FREEZE 後)
|
||||
## Status(2025-12-14)
|
||||
|
||||
- E5-1(Free Tiny Direct)は ✅ GO(+3.35%)
|
||||
- E5-2(Header refill write-once)は ⚪ NEUTRAL → FREEZE
|
||||
- E5-3(env shape 等)は **DEFER**
|
||||
- 次の芯: **E5-4(Malloc Tiny Direct)** = E5-1 の成功パターンを alloc 側へ複製
|
||||
- E5-4(Malloc Tiny Direct)は ⚪ NEUTRAL(-0.48%)→ **FREEZE**
|
||||
|
||||
狙い:
|
||||
- `malloc()` wrapper から `tiny_alloc_gate_fast()` 呼び出しの “ゲート税” を削り、
|
||||
**wrapper → malloc_tiny_fast_for_class()** へ最短で入る。
|
||||
結論:
|
||||
- malloc 側は wrapper/gate が既に薄く、E5-1 の “重複排除” が成立しなかった(LTO/inlining の天井)
|
||||
- 研究箱として default OFF のまま保持し、本線は次の芯へ進む
|
||||
|
||||
前提:
|
||||
- “Tiny を使ってはいけない” モード(POOL_ONLY 等)を壊さない(= `g_tiny_route[]` は必ず尊重)。
|
||||
@ -119,4 +119,3 @@ scripts/verify_health_profiles.sh
|
||||
- `docs/analysis/ENV_PROFILE_PRESETS.md` に:
|
||||
- 効果、A/B、rollback(`HAKMEM_MALLOC_TINY_DIRECT=0`)を追記
|
||||
- `CURRENT_TASK.md` を更新
|
||||
|
||||
|
||||
@ -15,9 +15,9 @@
|
||||
|
||||
Update:
|
||||
- E5-1(Free Tiny Direct Path)✅ GO(+3.35% mean / +3.36% median)→ 指示書: `docs/analysis/PHASE5_E5_1_FREE_TINY_DIRECT_NEXT_INSTRUCTIONS.md`
|
||||
- E5-2(Header write to refill boundary)⚪ NEUTRAL → FREEZE(追わない)
|
||||
- E5-3(env shape 等)DEFER → 次は E5-4(malloc 側 direct)
|
||||
- E5-4 指示書: `docs/analysis/PHASE5_E5_4_MALLOC_TINY_DIRECT_NEXT_INSTRUCTIONS.md`
|
||||
- E5-2(Header write-once)⚪ NEUTRAL → FREEZE
|
||||
- E5-4(Malloc Tiny Direct)⚪ NEUTRAL → FREEZE → 結果: `docs/analysis/PHASE5_E5_4_MALLOC_TINY_DIRECT_AB_TEST_RESULTS.md`
|
||||
- 次の芯: **E6(ENV snapshot branch-shape fix)**(enabled 前提の分岐形、MIXED のみ opt-in)
|
||||
|
||||
---
|
||||
|
||||
|
||||
139
docs/analysis/PHASE5_E6_ENV_SNAPSHOT_SHAPE_NEXT_INSTRUCTIONS.md
Normal file
139
docs/analysis/PHASE5_E6_ENV_SNAPSHOT_SHAPE_NEXT_INSTRUCTIONS.md
Normal file
@ -0,0 +1,139 @@
|
||||
# Phase 5 E6: ENV Snapshot Branch-Shape Fix(次の指示書)
|
||||
|
||||
## 背景(E5-2 / E5-4 連続 NEUTRAL 後)
|
||||
|
||||
- `HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE` では `HAKMEM_ENV_SNAPSHOT=1` が常用。
|
||||
- しかし hot path 側(例: `malloc_tiny_fast_for_class()`)に
|
||||
`if (__builtin_expect(hakmem_env_snapshot_enabled(), 0))` のような “OFF 前提” hint が残っている。
|
||||
- これは **steady-state で毎回 mispredict** になり得る(enabled が真のとき)。
|
||||
|
||||
狙い:
|
||||
- 意味(semantic)は一切変えず、**分岐形だけ**を “enabled 前提” に寄せる。
|
||||
- ただし default build では `HAKMEM_ENV_SNAPSHOT=0` もあり得るので、**MIXED のみ opt-in** に限定する(戻せる)。
|
||||
|
||||
---
|
||||
|
||||
## Box Theory(箱の切り方)
|
||||
|
||||
- L0: `env_snapshot_shape_enabled()`(ENV gate, default OFF)
|
||||
- L1: “shape 変更” は call site だけ(境界 1 箇所ずつ)
|
||||
- Fail-fast: なし(意味不変なので)
|
||||
- 見える化: perf / branch-misses のみ(常時ログ禁止)
|
||||
|
||||
---
|
||||
|
||||
## Step 1: ENV gate を追加
|
||||
|
||||
新規:
|
||||
- `core/box/env_snapshot_shape_env_box.h`
|
||||
- ENV: `HAKMEM_ENV_SNAPSHOT_SHAPE=0/1`(default 0)
|
||||
- `static inline bool env_snapshot_shape_enabled(void)`
|
||||
|
||||
有効化ポリシー:
|
||||
- `MIXED_TINYV3_C7_SAFE` でのみ `bench_setenv_default("HAKMEM_ENV_SNAPSHOT_SHAPE","1")` を検討(GO 後)
|
||||
- 他プロファイルは default OFF のまま
|
||||
|
||||
---
|
||||
|
||||
## Step 2: call site を “enabled 前提” の形に変更(意味不変)
|
||||
|
||||
対象(例):
|
||||
- `core/front/malloc_tiny_fast.h` 内の複数箇所
|
||||
- `core/box/tiny_metadata_cache_hot_box.h`
|
||||
- `core/box/tiny_legacy_fallback_box.h`
|
||||
|
||||
置換パターン:
|
||||
|
||||
Before:
|
||||
```c
|
||||
if (__builtin_expect(hakmem_env_snapshot_enabled(), 0)) {
|
||||
const HakmemEnvSnapshot* env = hakmem_env_snapshot();
|
||||
x = env->tiny_c7_ultra_enabled;
|
||||
} else {
|
||||
x = tiny_c7_ultra_enabled_env();
|
||||
}
|
||||
```
|
||||
|
||||
After(shape gate ON のときだけ形を変える):
|
||||
```c
|
||||
if (__builtin_expect(env_snapshot_shape_enabled(), 0)) {
|
||||
if (__builtin_expect(!hakmem_env_snapshot_enabled(), 0)) {
|
||||
x = tiny_c7_ultra_enabled_env();
|
||||
} else {
|
||||
const HakmemEnvSnapshot* env = hakmem_env_snapshot();
|
||||
x = env->tiny_c7_ultra_enabled;
|
||||
}
|
||||
} else {
|
||||
if (__builtin_expect(hakmem_env_snapshot_enabled(), 0)) {
|
||||
const HakmemEnvSnapshot* env = hakmem_env_snapshot();
|
||||
x = env->tiny_c7_ultra_enabled;
|
||||
} else {
|
||||
x = tiny_c7_ultra_enabled_env();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
注意:
|
||||
- `HAKMEM_ENV_SNAPSHOT=0` のときに mispredict が増えないよう、shape は **MIXED だけ**で使う。
|
||||
|
||||
---
|
||||
|
||||
## Step 3: A/B(Mixed 10-run)
|
||||
|
||||
### A: shape OFF
|
||||
```sh
|
||||
HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE \
|
||||
HAKMEM_ENV_SNAPSHOT=1 \
|
||||
HAKMEM_ENV_SNAPSHOT_SHAPE=0 \
|
||||
./bench_random_mixed_hakmem 20000000 400 1
|
||||
```
|
||||
|
||||
### B: shape ON
|
||||
```sh
|
||||
HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE \
|
||||
HAKMEM_ENV_SNAPSHOT=1 \
|
||||
HAKMEM_ENV_SNAPSHOT_SHAPE=1 \
|
||||
./bench_random_mixed_hakmem 20000000 400 1
|
||||
```
|
||||
|
||||
判定:
|
||||
- GO: mean **+1.0% 以上**
|
||||
- ±1.0%: NEUTRAL → freeze
|
||||
- -1.0% 以下: NO-GO → freeze
|
||||
|
||||
---
|
||||
|
||||
## Step 4: branch-miss を確認(任意)
|
||||
|
||||
```sh
|
||||
HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE \
|
||||
HAKMEM_ENV_SNAPSHOT=1 HAKMEM_ENV_SNAPSHOT_SHAPE=0 \
|
||||
perf stat -e branches,branch-misses -- \
|
||||
./bench_random_mixed_hakmem 20000000 400 1
|
||||
|
||||
HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE \
|
||||
HAKMEM_ENV_SNAPSHOT=1 HAKMEM_ENV_SNAPSHOT_SHAPE=1 \
|
||||
perf stat -e branches,branch-misses -- \
|
||||
./bench_random_mixed_hakmem 20000000 400 1
|
||||
```
|
||||
|
||||
期待:
|
||||
- `branch-misses` が下がる(throughput も上がるのが理想)
|
||||
|
||||
---
|
||||
|
||||
## Step 5: 健康診断
|
||||
|
||||
```sh
|
||||
scripts/verify_health_profiles.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 6: 昇格(GO のときだけ)
|
||||
|
||||
- `core/bench_profile.h`(MIXED):
|
||||
- `bench_setenv_default("HAKMEM_ENV_SNAPSHOT_SHAPE","1")`
|
||||
- `docs/analysis/ENV_PROFILE_PRESETS.md` に A/B と rollback(`=0`)追記
|
||||
- `CURRENT_TASK.md` を更新
|
||||
|
||||
@ -74,3 +74,4 @@ scripts/verify_health_profiles.sh
|
||||
- E5 次の芯: `docs/analysis/PHASE5_E5_NEXT_INSTRUCTIONS.md`
|
||||
- E5-1 昇格: `docs/analysis/PHASE5_E5_1_FREE_TINY_DIRECT_NEXT_INSTRUCTIONS.md`
|
||||
- E5-4 次: `docs/analysis/PHASE5_E5_4_MALLOC_TINY_DIRECT_NEXT_INSTRUCTIONS.md`
|
||||
- E6 次: `docs/analysis/PHASE5_E6_ENV_SNAPSHOT_SHAPE_NEXT_INSTRUCTIONS.md`
|
||||
|
||||
Reference in New Issue
Block a user