diff --git a/docs/analysis/SMALLOBJECT_V7_DESIGN.md b/docs/analysis/SMALLOBJECT_V7_DESIGN.md index 798b397c..5de59d97 100644 --- a/docs/analysis/SMALLOBJECT_V7_DESIGN.md +++ b/docs/analysis/SMALLOBJECT_V7_DESIGN.md @@ -703,6 +703,143 @@ HAKMEM_SMALL_HEAP_V7_CLASSES=0x60 # bit5(C5) + bit6(C6) --- +## 12. Phase v7-6: Mixed A/B + Learner 設計 + +### 12-1. Mixed 16-1024B A/B 結果 + +**ベンチ条件**: +- Profile: MIXED_TINYV3_C7_SAFE +- Benchmark: bench_random_mixed_hakmem 1000000 400 1 +- Size range: 16-1024B (全クラス) + +| Config | Runs | Avg Throughput | Delta vs OFF | +|--------|------|----------------|--------------| +| v7 OFF | 5 | **41.3M ops/s** | baseline | +| v7 C6-only (0x40) | 3 | **41.5M ops/s** | +0.5% | +| v7 C5+C6 (0x60) | 8 | **38.0M ops/s** | **-8.0%** | + +### 12-2. 発見と考察 + +**重要な発見**: ワークロードによって最適な route が異なる + +| ワークロード | C6-only v7 | C5+C6 v7 | 推奨 | +|-------------|------------|----------|------| +| C5+C6 専用 (257-768B) | baseline | **+4.3%** | C5+C6 v7 | +| Mixed 16-1024B | +0.5% | **-8.0%** | C6-only v7 | + +**原因分析**: +- Mixed では C0-C4 の alloc/free が多く、C5/C6 の比率が低い +- C5 を v7 に送ると、MID v3 / legacy より遅い経路を通る +- C5+C6 専用ベンチでは C5 比率が高く v7 のメリットが出る + +**結論**: C5 の route は workload-dependent。Learner で動的に切り替えるべき。 + +### 12-3. Policy/Learner 連携設計 + +#### Stats → Learner データフロー + +``` +SmallPageStatsV7 (retire時) + │ + ▼ +SmallLearnerStatsV7 (集約) + │ + ▼ +PolicyLearner (判定) + │ + ▼ +SmallPolicyV7.route_kind[] (更新) +``` + +#### SmallPageStatsV7 から Learner が読むべきフィールド + +```c +// 既存 (smallobject_cold_iface_v7_box.h) +typedef struct SmallPageStatsV7 { + uint8_t class_idx; // ← クラス別集計のキー + uint64_t alloc_count; // ← Learner: クラスごとの alloc 頻度 + uint64_t free_count; // ← Learner: クラスごとの free 頻度 + uint64_t remote_free_count;// ← Learner: remote free 比率 + uint16_t peak_live; // ← Learner: ピーク使用量 + uint32_t lifetime_ms; // ← Learner: page 寿命 +} SmallPageStatsV7; +``` + +#### Learner 側の集約構造案 + +```c +typedef struct SmallLearnerStatsV7 { + // Per-class counters (C0-C7) + struct { + uint64_t total_allocs; // 累積 alloc 数 + uint64_t total_frees; // 累積 free 数 + uint64_t v7_allocs; // v7 経由の alloc 数 + uint64_t v7_frees; // v7 経由の free 数 + uint64_t tls_hits; // TLS segment hit 数 + uint64_t regionid_lookups; // RegionIdBox fallback 数 + uint32_t avg_page_lifetime_ms; + } per_class[8]; + + // Global counters + uint64_t sample_count; // 集計サンプル数 + uint64_t last_update_epoch; // 最終更新 epoch +} SmallLearnerStatsV7; +``` + +#### 更新頻度 + +- **オプション A**: N秒ごと(例: 10秒) +- **オプション B**: Nページ retire ごと(例: 100 pages) +- **推奨**: オプション B(イベント駆動、低オーバーヘッド) + +#### Policy 更新 API シグネチャ + +```c +// Learner → Policy 更新 +void small_policy_v7_update_from_learner( + const SmallLearnerStatsV7* stats, + SmallPolicyV7* policy_out +); + +// 判定ロジック例 +// if (stats->per_class[5].v7_allocs / stats->per_class[5].total_allocs > 0.5 +// && stats->per_class[5].tls_hits / stats->per_class[5].v7_frees > 0.8) { +// policy_out->route_kind[5] = SMALL_ROUTE_V7; // C5 → v7 +// } else { +// policy_out->route_kind[5] = SMALL_ROUTE_MID_V3; // C5 → MID v3 +// } +``` + +### 12-4. 層の分担(明文化) + +``` +L3 (Policy/Learner): + - Stats を集約 + - route_kind[] を決定 + - snapshot を差し替え + +L1/L0 (ULTRA/v7/MID v3): + - snapshot を読むだけ + - ENV や Learner を直接参照しない + - route_kind[class_idx] に従って分岐 +``` + +### 12-5. 保留事項 + +以下は v7-6 の結果を踏まえて別フェーズで検討: + +1. **C4 v7 拡張**: Mixed A/B と Learner 設計の後に判断する +2. **Intrusive LIFO / 完全 headerless**: v7-6 の結果を見てから検討 + +### 12-6. 次のステップ候補 + +1. **Learner 実装 (Phase v7-7)**: SmallLearnerStatsV7 の実装と Policy 更新ロジック +2. **Workload Detection**: alloc/free パターンから workload を推定 +3. **Dynamic Route Switching**: 実行時に C5 の route を v7 ↔ MID v3 で切り替え + +--- + **Document Updated**: 2025-12-12 **Phase v7-5a Status**: COMPLETE **Phase v7-5b Status**: COMPLETE +**Phase v7-6 Status**: COMPLETE