Phase v7-6: Mixed A/B + Learner design (workload-dependent routes)
Mixed 16-1024B A/B results: - v7 OFF: 41.3M ops/s (baseline) - v7 C6-only: 41.5M ops/s (+0.5%) - v7 C5+C6: 38.0M ops/s (-8.0%) ← C5 hurts in Mixed! Key finding: C5 route is workload-dependent - C5+C6 heavy (257-768B): C5+C6 v7 is +4.3% faster - Mixed 16-1024B: C5+C6 v7 is -8.0% slower Learner design: - SmallLearnerStatsV7 aggregate structure - small_policy_v7_update_from_learner() API - L3 updates snapshot, L1/L0 reads only C4 v7 and Intrusive LIFO marked as on-hold. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -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
|
||||
|
||||
Reference in New Issue
Block a user