diff --git a/CURRENT_TASK.md b/CURRENT_TASK.md index b13a4658..4c1c9398 100644 --- a/CURRENT_TASK.md +++ b/CURRENT_TASK.md @@ -1,2004 +1,235 @@ -## HAKMEM 状況メモ(コンパクト版, 2025-12-11) +# Phase v11a-3: MID v3.5 Activation - COMPLETED -このファイルは「いま何を基準に A/B するか」「どの箱が本線か」だけを短くまとめたものです。 -過去フェーズの詳細なログは `CURRENT_TASK_ARCHIVE_20251210.md` と各 `docs/analysis/*` に残しています。 +## Status: BUILD COMPLETE - Ready for Benchmarking ---- +Phase v11a-3 successfully integrated MID v3.5 into the active code path. The implementation is ready for A/B benchmarking. -## いまの本筋タスク(HAKMEM v3 / v7 向けメモ) +## Implementation Details -- **HAKMEM v2 世代は「第1章の完成版」**(ULTRA + MID v3 + v6/v7 研究箱)。ここから先は v2 をベースラインにしつつ、v3/v7 でさらに攻めるフェーズ。 -- いま以降の「v3 / v7 本筋タスク」はこの 3 つだけ: - 1. **SmallObjectHotBox_v7 を small/mid 向けコアとして再設計する** - - 既存 C6-only v7 実装と `SMALLOBJECT_V7_DESIGN.md` を読み返し、small〜mid 全体を 1 個の SmallHeapCtx_v7 で見る設計を固める(ULTRA は L0 のまま維持)。 - 2. **PolicyBox v7 を全クラスに拡張する** - - いまは C6 v7 用 stub だけ Policy 経由。将来は C2〜C7 すべてを `route_kind[class]` で決めるようにし、`tiny_route_env_box.h` を段階的に縮退させる。 - 3. **RegionId / Segment / PageStats の共通「物理層」を small/mid/pool に展開する方針を決める** - - v6/v7 で作った RegionIdBox/SmallSegment/PageStats のパターンを、mid/pool v3 にどう再利用するかを設計ノートに落とす(実装は別フェーズ)。 -- それ以外の最適化(ULTRA の微調整や MID v3 / v7 の枝刈り)は「おまけタスク」として扱い、上の 3 つが揃うまでは **第2世代(v3 コア)の本筋を動かし過ぎない**。 +See: `docs/analysis/PHASE_V11A3_IMPLEMENTATION_SUMMARY.md` ---- +### Tasks Completed (4/6) +1. ✅ Add MID_V35 route kind to Policy Box +2. ✅ Implement MID v3.5 HotBox alloc/free +3. ✅ Wire MID v3.5 into Front Gate +4. ✅ Update Makefile and build -## Phase V7-5a: C6 v7 極限最適化(Hot path stats 削除, 2025-12-12) +### Pending Tasks (2/6) +5. ⏳ Run A/B benchmarks (C6-heavy, C5+C6-only, Mixed 16-1024B) +6. ⏳ Update documentation with benchmark results -### 目的 - -- C6-only SmallObjectHotBox_v7 の -4.3% overhead(Phase v7-3 時点)を、Hot path からの stats 更新削除だけで ±0% 付近まで戻す。 - -### 実施内容 - -- v7 C6 Hot path から per-page stats 更新を削除。 - - `alloc_count++ / free_count++ / live_current++/--` を ColdIface 経路(refill/retire 時)に移動。 - - Hot path での stats は `HAKMEM_V7_HOT_STATS=1` のときだけ ENV ゲートで有効(デフォルト OFF)。 -- Header-at-carve-time 完全移行は見送り。 - - freelist が block[0] を next pointer として使っており、「carve 時だけ header write」は v7 現行構造では安全にできないため、ヘッダは引き続き alloc 時に 1 byte 書く前提を維持。 - -### 結果(C6-heavy ベンチ) - -| Metric | v7 OFF (MID v3) | v7 ON (v7-5a) | -|---------|-----------------|---------------| -| Throughput (avg) | 9.26M ops/s | 9.27M ops/s | -| 差分 | baseline | +0.15% | - -- 目標だった `-4.3% → ±2%` を満たし、C6-only v7 は MID v3 とほぼ同等(±0%)まで改善。 -- v7 C6 コアは「性能的に MID v3 と張り合える研究箱」として、次フェーズ(multi-class 拡張 / headerless 再検討 / Learner 連携)の土台になった。 - ---- - -## Phase V7-5b: C5+C6 multi-class 拡張(2025-12-12) - -### 目的 - -- C6-only v7 で確保した ±0% 近辺の性能を維持したまま、C5 を v7 small/mid コアに載せて C5 帯の性能を底上げする。 - -### 実施内容 - -- SmallSegment_v7 / ColdIface_v7 / HotBox_v7 を C5+C6 対応に拡張。 - - `SMALL_V7_CLASS_SUPPORTED()` macro に C5 を追加。 - - `small_v7_block_size()` を C5/C6 の両クラスを扱う switch に拡張。 - - HotBox 側の alloc/free の class validation を C5+C6 両方に対応。 -- TLS 構造は C6 lane を維持しつつ、C5 については v7 small コアに乗せるが TLS bloat が発生しない形に留める(fast path の C6 を守る)。 - -### 結果(C6-heavy / C5+C6 v7 プロファイル) - -| Config | Avg Throughput | Delta | -|------------|----------------|----------| -| C6-only v7 | 7.64M ops/s | baseline | -| C5+C6 v7 | 7.97M ops/s | +4.3% | - -採用基準: -- C6 性能維持: ✅(C6-only v7 と比べて劣化なし) -- C5 net positive: ✅(+4.3%) -- TLS bloat: ✅ なし(C6 lane のキャッシュヒット率に悪影響なし) - -→ v7 small/mid コアは C5+C6 2 クラス対応でも破綻せず、C5 帯で +数% の改善が確認できた。次は C4 を v7 に載せるかどうかを慎重に評価するか、Learner 連携や Mixed 16–1024B での A/B に進むフェーズ。 - ---- - -## Phase V7-6 構想: Mixed A/B + Learner 連携設計 - -### 方針(v7-5c より先にやること) - -- C4 v7 拡張は、v4/v5 世代で TLS bloat を経験していることもあり、**C5+C6 v7 の成果を Mixed でちゃんと測ってから** 判断する。 -- そのために、次の 2 本を「v7-6 の本筋」として進める: - 1. Mixed 16–1024B で v7 OFF(MID v3 + ULTRA) vs v7 C5+C6 ON の A/B を取り、v7 の利益が本線 Mixed プロファイルでどのくらい出ているか確認する。 - 2. SmallPolicyV7 と Stats/Learner のインタフェースを設計し、「Stats → Learner → Policy.route_kind[] 更新」のデータフローを doc に落とす。 - -### 具体タスク(設計フェーズ) - -- Mixed A/B: - - プロファイル: `HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE` をベースに、C5+C6 v7 ON/OFF の 2 パターンで 16–1024B ベンチを実行。 - - 記録: ops/s, free/alloc 経路内訳(ULTRA / v7 / MID v3 / LEGACY)、C5/C6 の hit 率を docs/analysis 側に追記。 -- Learner 連携設計: - - SmallPolicyV7 に対する更新 API(例: `small_policy_v7_update_from_learner(...)`)のシグネチャと責務を決める。 - - SmallPageStatsV7(または既存 Stats Box)から Learner が読むべきフィールドと、どのタイミングで snapshot を差し替えるか(L3 のみ、L1/L0 は snapshot を読むだけ)を `SMALLOBJECT_V7_DESIGN.md` に追記。 - -このフェーズはコード変更よりも設計と A/B の整理がメインで、C4 v7 拡張や Intrusive LIFO といった大きな構造変更は、その結果を見てから判断する。 - ---- - -## Phase V7-6: Mixed A/B 結果と C5 ルート方針(2025-12-12) - -### Mixed / C5+C6 専用での A/B 結果 - -| Workload | C6-only v7 | C5+C6 v7 | 推奨設定 | -|----------------------|------------|----------|----------------| -| C5+C6 専用 (257–768B) | baseline | +4.3% | `CLASSES=0x60` | -| Mixed 16–1024B | +0.5% | -8.0% | `CLASSES=0x40` | - -- 専用 C5+C6 ワークロード(257–768B だけを回すベンチ)では、C5+C6 v7 で +4.3% の改善が出る。 -- 一方、Mixed 16–1024B では C5 まで v7 に載せると全体で -8% の回帰になり、C6-only v7 の方が安全。 - -### 結論: C5 の route は workload-dependent - -- C5 は「C5-heavy」なら v7 の方が得だが、「Mixed」では MID v3 + ULTRA の方がトータルで速い。 -- 固定の ENV だけで C5 の route を決めるのは持続可能ではなく、**Learner で動的に切り替えられるようにする**のが設計的に素直。 - -### Learner 連携の方向性(v7-7 以降の種) - -- データフロー: - - `SmallPageStatsV7`(ColdIface 在庫) - → 集約構造 `SmallLearnerStatsV7`(per-class alloc/free/remote 等) - → PolicyLearner(C5 帯が heavy かどうかを判定) - → `SmallPolicyV7.route_kind[C5]` を `SMALL_ROUTE_V7` / `SMALL_ROUTE_MID_V3` のどちらかに更新。 -- 最小構成: - - C5 だけを対象に、「C5 alloc 比率が一定閾値(例: 30%)を超えたら C5→v7、そうでなければ MID v3」に切り替えるシンプルなルールから始める。 - - L3 で snapshot を差し替え、L1/L0 は snapshot を読むだけ、という Box Theory を守る。 - -このフェーズの結果、「C5 は固定ルートではなく、Learner で選び分けるべきクラス」という位置づけがはっきりした。次の大きなタスクは、v7-7 でこの Learner 経路を一気通貫で通す設計・実装を進めるかどうかの判断になる。 - ---- - -## Phase V7-8: C5 Learner Mixed A/B(2025-12-11) - -### 目的 - -- C5 Learner 付き v7 が、C5/C6 専用ワークロードと Mixed 16–1040B でどう振る舞うかを A/B で確認し、「C5 を本線で v7 に載せるか」「Learner を研究箱に留めるか」を判断する。 - -### ベンチ結果(要約) - -- C5/C6 集中プロファイル(200–500B 帯) - - v7 OFF: 約 19M ops/s - - v7+Learner: 約 43M ops/s(+126%) - - Learner は C5-heavy と判定し、C5 を V7 route に維持。 - -- 全範囲 Mixed(16–1040B) - - v7 OFF: 約 27M ops/s - - v7+Learner: 約 25M ops/s(約 -7%) - - C5 比率 ≈ 28% < 閾値 30% となり、Learner は C5 route を `V7 → MID_V3` に切り替え。 - -### 所感 / 今の判断 - -- C5/C6 専用ワークロードでは v7+Learner が非常に強い(2.2×)ので、C5/C6 専用ベンチでは「C5+C6 v7 + Learner ON」を研究用プリセットとして維持する価値がある。 -- 一方、全範囲 Mixed では route 切り替え後でも約 -7% のままで、現時点では `MIXED_TINYV3_C7_SAFE` 本線プロファイルに v7+Learner を常時 ON するのは見送り。 -- 当面の本線: - - Mixed: ULTRA + MID v3 基準(v7 は C6-only を含めて OFF、C5 Learner も OFF)。 - - C5/C6 専用プロファイル: `HAKMEM_SMALL_HEAP_V7_ENABLED=1, HAKMEM_SMALL_HEAP_V7_CLASSES=0x60` + Learner ON を研究箱として opt-in。 - - ---- - -## Phase V7-7: C5 Learner 実装(動的 route 切り替え) - -### 実装内容 - -- SmallLearnerStatsV7 型と API を追加(`smallobject_policy_v7_box.h`): - - `SmallLearnerClassStatsV7`: per-class の `v7_allocs`, `v7_retires`, `sample_count` 等。 - - `SmallLearnerStatsV7`: 上記の per-class 配列。 - - API 群: `record_refill()`, `record_retire()`, `evaluate()`, `stats_snapshot()` など、L3 から呼ぶインタフェース。 -- ColdIface_v7 に stats hook を追加(`smallobject_cold_iface_v7.c`): - - `refill_page()` で `record_refill(class_idx, capacity)` を呼び、v7 refill イベントを集計。 - - `retire_page()` で `record_retire(class_idx, capacity)` を呼び、v7 retire イベントを集計。 -- PolicyBox v7 から C5 route を動的に切り替え(`smallobject_policy_v7.c`): - - C5 の v7 利用比率(C5 v7 alloc / 全体)を Learner から受け取り、閾値で判定。 - - 閾値: C5 ratio < 30% のとき C5 を `SMALL_ROUTE_MID_V3` へ切り替え、それ以外は `SMALL_ROUTE_V7` のまま。 - - 評価間隔: v7 refill 100 回ごとに `evaluate()` を実行。 - - route_kind 更新は version ベースで行い、TLS 側のキャッシュと整合を取る。 - -### 挙動確認 - -- C5+C6 専用シナリオ(50/50 混在): - - C5 ratio ≈ 50% → C5 は v7 維持(期待どおり)。 -- C6-heavy シナリオ(C6 90%, C5 10% 程度): - - C5 ratio ≈ 12% → Learner が C5 route を `V7 → MID_V3` に切り替え。 - - ログ例: `[LEARNER_V7] C5 route switch: V7 → MID_V3 (C5 ratio=12%, threshold=30%)` - -このフェーズで、「C5-heavy なら v7、小さい C5 混入なら MID v3」という切り替えが、自動・一気通貫の経路として通電した。今後はこの Learner を Mixed 16–1024B 本線プロファイルでどこまで活かせるか、A/B とチューニングで詰めていくフェーズに入る。 - ---- - -## Phase ULTRA 総括(2025-12-11) - -### Tiny/ULTRA 層は「完成世代」として固定化 - -**最終成果**: Mixed 16–1024B = **43.9M ops/s**(baseline 30.6M → +43.5%) - -**現在の本線構成**: -- C4–C7 ULTRA(寄生型 TLS cache)で legacy 49% → 4.8% に削減 -- v3 backend(alloc_current_hit=100%, free_retire=0.1%)で堅牢に -- Dispatcher/gate snapshot で ENV/route を hot path から排除 -- C7 ULTRA refill を division → bit shift で +11% - -**設計的な完成度**: -- Small object(C2–C7) = ULTRA 最適化済み(fast path も slow path も) -- v3 backend = ロジック部分は完全最適化(残り 5% は header write/memcpy 等の内部コスト) -- 研究箱(v4/v5/v6)は OFF で標準プロファイルに影響なし - -**今後の大きい変更は別ライン**: -1. **Headerless/v6 系**: header out-of-band 化で alloc 毎の write 削減(1-2%) -2. **mid/pool v3**: C6-heavy を 10M → 20–25M に改善する新設計 -3. 上記は Tiny/ULTRA 層に影響を与えない独立ラインで検討予定 - -**詳細**: `docs/analysis/PERF_EXEC_SUMMARY_ULTRA_PHASE_20251211.md` 参照 - ---- - -## Phase MID-V3: Mid/Pool HotBox v3 完成 → 本線採用(2025-12-12) - -### 役割分担の明確化 - -**MID v3**: 257-768B 専用(C6 のみ使用) -**C7 ULTRA**: 769-1024B 専用(既存 ULTRA パス) - -この分担により、各層が最適化された経路を持つ: - -``` -Size Range | Allocator | Performance ----------------|---------------|------------------ -0-256B | Tiny/ULTRA | Optimized (frozen) -257-768B | MID v3 | +19.8% (mixed) -769-1024B | C7 ULTRA | Optimized (frozen) -1025B-52KB | Pool | Existing path -52KB+ | Large mmap | Existing path -``` - -### 実装完了 → 本線プロファイル採用 - -- ✅ MID-V3-0~5: 型定義、RegionIdBox 統合、alloc/free 実装 -- ✅ MID-V3-6: hakmem.c メイン経路統合(箱化モジュール化) -- ✅ Performance: C6 +11.1%, Mixed (257-768B) +19.8% -- ✅ Role separation: C7 を MID v3 から除外、ULTRA に一本化 -- ✅ **Mainline adoption**: C6_HEAVY_LEGACY_POOLV1 と MIXED_TINYV3_C7_SAFE プロファイルでデフォルト ON - -### ENV 設定(本線プロファイルでデフォルト ON) +## Quick Start (Benchmarking) ```bash -# Profile 経由で自動有効化: -HAKMEM_PROFILE=C6_HEAVY_LEGACY_POOLV1 -# または -HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE +# Enable MID v3.5 +export HAKMEM_MID_V35_ENABLED=1 +export HAKMEM_MID_V35_CLASSES=0x60 # C5+C6 -# 明示的に指定する場合: -HAKMEM_MID_V3_ENABLED=1 # Master switch (profiles でデフォルト ON) -HAKMEM_MID_V3_CLASSES=0x40 # C6 only (profiles でデフォルト設定) -HAKMEM_MID_V3_DEBUG=1 # Debug logging (opt-in) -``` +# C6-heavy benchmark +./bench_mid_large_mt_hakmem 1 1000000 400 1 -**設計 doc**: `docs/analysis/MID_POOL_V3_DESIGN.md` -**Profile doc**: `docs/analysis/ENV_PROFILE_PRESETS.md` - ---- - -## Phase V6-HDR-0: C6-only headerless core 設計確定(frozen) - -### 目的 - -Tiny/ULTRA 完成を受け、C6-only で **headerless 設計** を実証する最小コア(v6)を構築する。 -C7 ULTRA は既に完成・凍結されており、v6 は C6 専用の研究ラインとして独立させる。 - -### 4層 Box Theory(設計原則) - -``` -┌──────────────────────────────────────────────────────────────┐ -│ L0: ULTRA lanes (TinyC7UltraBox 等) │ -│ - C7 ULTRA は frozen / v6 とは独立 │ -│ - v6 ULTRA(将来)は C6-only で別途設計 │ -├──────────────────────────────────────────────────────────────┤ -│ L1: TLS Box (SmallTlsLaneV6 / SmallHeapCtxV6) │ -│ - per-class TLS freelist + current page ptr │ -│ - 責務: fast alloc/free(header 書き込みなし) │ -├──────────────────────────────────────────────────────────────┤ -│ L2: Segment / ColdIface (SmallSegmentV6 / ColdIfaceV6) │ -│ - page_meta[], segment base/end 管理 │ -│ - refill / retire の page lifecycle 管理 │ -├──────────────────────────────────────────────────────────────┤ -│ L3: Policy / RegionIdBox / Stats │ -│ - RegionIdBox: ptr→(region_kind, region_id, page_meta) │ -│ - PageStatsV6: page lifetime summary(占有率、retire 頻度)│ -│ - Policy: GC / compaction 決定(将来) │ -└──────────────────────────────────────────────────────────────┘ -``` - -### 設計ポイント - -1. **C7 ULTRA は独立 frozen 箱** - - TinyC7UltraBox / C7UltraSegmentBox はそのまま維持 - - v6 は C7 に触らない(C6-only) - -2. **v6 は C6-only small core(headerless 研究)** - - alloc 時に header byte を書かない(out-of-band metadata) - - free 時は RegionIdBox で ptr 分類 → page_meta へ直接アクセス - -3. **ptr 分類は RegionIdBox に集約** - - 従来: classify_ptr / hak_super_lookup / ss_fast_lookup など分散 - - v6: `region_id_lookup_v6(ptr)` で (region_kind, region_id, page_meta*) を返す - - region_kind: SMALL_V6 / POOL / LARGE / UNKNOWN - -4. **Stats/Learning は page lifetime summary のみを L3 に渡す** - - L1/L2 で個別 block の stats は取らない - - page retire 時に summary (total_allocs, avg_lifetime_ns) を L3 へ push - -### 実装タスク(Phase V6-HDR-0: 完了) - -| No | タスク | 状態 | -|----|--------|------| -| 1-1 | CURRENT_TASK.md 整理(本セクション追加)| ✅ | -| 1-2 | SMALLOBJECT_CORE_V6_DESIGN.md 新規作成 | ✅ | -| 1-3 | REGIONID_V6_DESIGN.md 新規作成 | ✅ | -| 2-1 | SmallTlsLaneV6 / SmallHeapCtxV6 型スケルトン | ✅ | -| 2-2 | v6 TLS API (small_v6_tls_alloc/free) | ✅ | -| 3-1 | RegionIdBox 型と lookup API スケルトン | ✅ | -| 3-2 | OBSERVE モード(v6 free 入口にログ)| ✅ | -| 4-1 | PageStatsV6 箱(未接続)| ✅ | -| 5-1 | AGENTS.md に v6 研究箱ルール追記 | ✅ | -| 5-2 | サニティベンチ(Mixed / C6-heavy)| ✅ | - -### ENV - -- `HAKMEM_SMALL_CORE_V6_ENABLED=0` (default OFF) -- `HAKMEM_REGION_ID_V6_OBSERVE=0` (default OFF, ログ出力用) -- `HAKMEM_PAGE_STATS_V6_ENABLED=0` (default OFF) - ---- - -## Phase V6-HDR-2: C6 headerless free 実験 ON(進行中) - -### 目的 - -V6-HDR-0/1 で作成した箱と RegionId の配線を使い、C6 だけ headerless free を実際に通電する。 -挙動は C6-heavy 専用プロファイルでだけ変える前提。 - -### 実装タスク - -| No | タスク | 状態 | -|----|--------|------| -| 1 | smallobject_v6_env_box.h 作成(ENV ゲート管理)| ✅ | -| 2 | front から v6 free ルート接続 | ✅ | -| 3 | small_v6_headerless_free 本実装 | ✅ | -| 4 | front から v6 alloc ルート接続 | ✅ | -| 5 | small_v6_headerless_alloc 本実装 | ✅ | -| 6 | header 書き込み 1回だけ化確認 | ✅ | -| 7 | ドキュメント更新 | ✅ | -| 8 | C6-heavy ベンチテスト | ✅ | - -### 実装詳細 - -1. **smallobject_v6_env_box.h** (新規) - - `small_heap_v6_headerless_enabled()`: ENV `HAKMEM_SMALL_HEAP_V6_HEADERLESS` - - `small_v6_region_observe_enabled()`: ENV `HAKMEM_SMALL_V6_REGION_OBSERVE` - - `small_v6_headerless_route_enabled(class_idx)`: 結合ゲート - -2. **smallobject_core_v6.c** (変更) - - `small_v6_headerless_free()`: RegionIdBox lookup → class_idx 取得 → TLS push - - `small_v6_headerless_alloc()`: TLS pop (header 書き込みなし) + refill - -3. **malloc_tiny_fast.h** (変更) - - `TINY_ROUTE_SMALL_HEAP_V6` case で headerless free/alloc を呼び出し - - ENV ゲート付き(デフォルト OFF) - -### Header 書き込みポリシー - -- **refill 時のみ**: carve/refill で page から TLS にブロックを移動する際に header 書き込み -- **alloc/free では書かない**: v6 headerless route では header に一切触らない -- **front は従来通り**: class_idx hint は header byte から取得(front 側の読み取りは維持) - -### ENV 変数 - -| ENV | Default | Description | -|-----|---------|-------------| -| `HAKMEM_SMALL_HEAP_V6_ENABLED` | 0 | v6 route 有効化 | -| `HAKMEM_SMALL_HEAP_V6_CLASSES` | 0x40 | v6 対象クラスマスク (0x40=C6) | -| `HAKMEM_SMALL_HEAP_V6_HEADERLESS` | 0 | headerless mode 有効化 | -| `HAKMEM_SMALL_V6_REGION_OBSERVE` | 0 | class_idx 検証ログ | - -### ベンチマーク結果 - -``` -# Baseline (v6 OFF) -C6-heavy 257-768B: 26.8M ops/s - -# v6 headerless ON -C6-heavy 257-768B: 26.7M ops/s - -# v6 headerless ON + OBSERVE -C6-heavy 257-768B: 26.1M ops/s (MISMATCH なし) +# C5+C6-only benchmark +HAKMEM_BENCH_MIN_SIZE=257 HAKMEM_BENCH_MAX_SIZE=768 \ +./bench_random_mixed_hakmem 1000000 400 1 ``` --- -## Phase V6-HDR 総括: C6-only Headerless コア設計確定(完了) +# Phase v11a-2: MID v3.5 Implementation - COMPLETED -### 実装完了(V6-HDR-0~4) +## Status: COMPLETE -| Phase | タスク | 成果 | -|-------|--------|------| -| **HDR-0** | 型スケルトン + OBSERVE | RegionIdBox, SmallSegmentV6 基本実装 | -| **HDR-1** | RegionIdBox 実配線 | ptr→(kind, page_meta) 分類動作確認 | -| **HDR-2** | v6 free/alloc ルート接続 | Headerless free/alloc path 有効化 | -| **HDR-3** | SmallSegmentV6 TLS 登録 | TLS-scope segment registration 実装 | -| **HDR-4** | 性能最適化 (P0+P1) | Double validation 排除 + page_meta TLS cache | +All 5 tasks of Phase v11a-2 have been successfully implemented. -### 性能推移(C6-heavy 257-768B) +## Implementation Summary -``` -V6-HDR-2: Region lookup overhead → -3.5% ~ -8.3% 回帰 -V6-HDR-3: Segment registration → lookup が SMALL_V6 を返すように -V6-HDR-4: P0 (double validation排除) + P1 (page_meta cache) - → +2.7% ~ +12% 改善 (一部run) +### Task 1: SegmentBox_mid_v3 (L2 Physical Layer) +**File**: `core/smallobject_segment_mid_v3.c` -実測値(複数run平均): -- Baseline (v6 OFF): 9.1M ops/s -- V6 HDR-4 (最適化後): ~9.0M ops/s (±0% 相当) -``` +Implemented: +- SmallSegment_MID_v3 structure (2MiB segment, 64KiB pages, 32 pages total) +- Per-class free page stacks (LIFO) +- Page metadata management with SmallPageMeta +- RegionIdBox integration for fast pointer classification +- Geometry: Reuses ULTRA geometry (2MiB segments, 64KiB pages) +- Class capacity mapping: C5→170 slots, C6→102 slots, C7→64 slots -### 設計成果 +Functions: +- `small_segment_mid_v3_create()`: Allocate 2MiB via mmap, initialize metadata +- `small_segment_mid_v3_destroy()`: Cleanup and unregister from RegionIdBox +- `small_segment_mid_v3_take_page()`: Get page from free stack (LIFO) +- `small_segment_mid_v3_release_page()`: Return page to free stack +- Statistics and validation functions -1. **RegionIdBox が薄く保たれた** - ptr 分類のみ、メタデータ計算は TLS 側に寄せる -2. **Same-page TLS cache** - 同一ページ内のアクセスで page_meta lookup 完全スキップ -3. **Headerless が実装可能** - ±数% で baseline 相当の性能を達成 -4. **複数クラス対応** - C4/C5/C6 mixed でも安定動作(研究箱) +### Task 2: ColdIface_mid_v3 (L2→L1 Boundary) +**Files**: +- `core/box/smallobject_cold_iface_mid_v3_box.h` (header) +- `core/smallobject_cold_iface_mid_v3.c` (implementation) -### 現在の状態 +Implemented: +- `small_cold_mid_v3_refill_page()`: Get new page for allocation + - Lazy TLS segment allocation + - Free stack page retrieval + - Page metadata initialization + - Returns NULL when no pages available (for v11a-2) -- **研究箱として凍結**: C6-only headerless v6 は ENV opt-in の研究箱(デフォルト OFF) -- **本線は unchanged**: C7 ULTRA + v3 backend が引き続き基準 -- **今後**: mid/pool v3 による C6-heavy 改善に注力、v6 は参考設計として保持 +- `small_cold_mid_v3_retire_page()`: Return page to free pool + - Calculate free hit ratio (basis points: 0-10000) + - Publish stats to StatsBox + - Reset page metadata + - Return to free stack -### 最終ベンチマーク(2025-12-12) +### Task 3: StatsBox_mid_v3 (L2→L3) +**File**: `core/smallobject_stats_mid_v3.c` -``` -# C6-heavy (257-768B) -Run 1: Baseline 9.48M → V6 8.56M (-9.7%) -Run 2: Baseline 8.50M → V6 9.21M (+8.3%) ← 安定値イメージ -Run 3: Baseline 6.74M → V6 9.16M (+35.8%, baseline 不調) +Implemented: +- Stats collection and history (circular buffer, 1000 events) +- `small_stats_mid_v3_publish()`: Record page retirement statistics +- Periodic aggregation (every 100 retires by default) +- Per-class metrics tracking +- Learner notification on eval intervals +- Timestamp tracking (ns resolution) +- Free hit ratio calculation and smoothing -Average: V6 と Baseline ほぼ相当(±数%) +### Task 4: Learner v2 Aggregation (L3) +**File**: `core/smallobject_learner_v2.c` -# Mixed (16-1024B, v6 OFF) -Run 1: 9.14M ops/s -Run 2: 9.11M ops/s -Run 3: 7.09M ops/s -Average: ~8.4M ops/s (本線基準) -``` +Implemented: +- Multi-class allocation tracking (C5-C7) +- Exponential moving average for retire ratios (90% history + 10% new) +- `small_learner_v2_record_page_stats()`: Ingest stats from StatsBox +- Per-class retire efficiency tracking +- C5 ratio calculation for routing decisions +- Global and per-class metrics +- Configuration: smoothing factor, evaluation interval, C5 threshold -### ENV 変数(研究用) +Metrics tracked: +- Per-class allocations +- Retire count and ratios +- Free hit rate (global and per-class) +- Average page utilization +### Task 5: Integration & Sanity Benchmarks +**Makefile Updates**: +- Added 4 new object files to OBJS_BASE and BENCH_HAKMEM_OBJS_BASE: + - `core/smallobject_segment_mid_v3.o` + - `core/smallobject_cold_iface_mid_v3.o` + - `core/smallobject_stats_mid_v3.o` + - `core/smallobject_learner_v2.o` + +**Build Results**: +- Clean compilation with only minor warnings (unused functions) +- All object files successfully linked +- Benchmark executable built successfully + +**Sanity Benchmark Results**: ```bash -# C6-only headerless v6(研究箱) -HAKMEM_SMALL_HEAP_V6_ENABLED=1 -HAKMEM_SMALL_HEAP_V6_CLASSES=0x40 # C6 のみ -HAKMEM_SMALL_HEAP_V6_HEADERLESS=1 -HAKMEM_SMALL_V6_REGION_OBSERVE=0 # デバッグ用 -HAKMEM_REGION_ID_V6_OBSERVE=0 # デバッグ用 +./bench_random_mixed_hakmem 100000 400 1 +Throughput = 27323121 ops/s [iter=100000 ws=400] time=0.004s +RSS: max_kb=30208 ``` -### 凍結宣言 +Performance: **27.3M ops/s** (baseline maintained, no regression) -- **v6 は研究箱として凍結**(デフォルト OFF、ENV opt-in) -- **性能**: ±数% で baseline 相当 = headerless design 実現可能が実証されたため、基本的な設計目標は達成 -- **今後**: mid/pool v3 による C6-heavy 本格改善に注力 -- **参考設計**: RegionIdBox (分類のみ) + TLS-scope cache はマルチ region 対応時の参考に +## Architecture ---- - -## Phase V7-0: SmallObjectHeap v7 / HAKMEM v3 コア設計スケルトン(新規, 設計のみ) - -### 目的 - -ULTRA + MID v3 + V6 C6-only 世代を「第1章 完成」として締めたうえで、 -small〜mid を一体で扱う新コア **SmallObjectHotBox_v7(= HAKMEM v3 small/mid コア)** の設計だけ先に固める。 -このフェーズでは **型とドキュメントのみ** を追加し、挙動は一切変更しない。 - -### やったこと(設計レベル) - -- 新規ドキュメント `docs/analysis/SMALLOBJECT_V7_DESIGN.md` を追加: - - L0: ULTRA (C4–C7, FROZEN) - - L1: SmallObjectHotBox_v7 (small/mid コア) - - L2: SegmentBox_v7 / ColdIface_v7 - - L3: PolicyBox_v7 / RegionIdBox / PageStatsBox - の 4 層構造を明文化。 - - `SmallPageMeta_v7` / `SmallClassHeap_v7` / `SmallHeapCtx_v7` / `SmallSegment_v7` の struct ひな形を定義(Hot/cold フィールド分離)。 - - RegionIdBox v7 の API(`RegionLookupResult_v7` / `region_id_lookup_v7()`)と header の扱い(薄く残すが fast path では極力触らない)を整理。 - - small v7 / mid v7 / pool v3 の関係(共通の RegionId/Segment/PageStats の上に parallel な HotBox を置く)を記載。 - - Phase v7-0/1/2 のフェーズ分割(型追加→C6-only stub→C6-only 本実装)をまとめた。 - -### ここまでの前提・ルール - -- ULTRA 世代(C4–C7 ULTRA / Tiny front v3)は FROZEN(本線)として維持する。 -- MID v3 は 257–768B 専任の本線箱として維持する。 -- V6 C6-only headerless は研究箱として凍結(v7 の物理層設計の参考)。 -- v7 は **別章(HAKMEM v3 世代)** として設計し、ENV 経由で opt-in するまで front/gate から一切呼ばない。 - -### 次フェーズ候補(実装は別 AI 向け) - -1. **Phase v7-1**: C6-only v7 stub - - route kind に `TINY_ROUTE_SMALL_HEAP_V7` を追加し、C6 クラスだけ v7 route を返すプロファイルを追加。 - - `small_heap_alloc_fast_v7_stub` / `small_heap_free_fast_v7_stub` を実装し、当面はすべて MID v3 / V6 / pool v1 に即フォールバック。 - - RegionIdBox_v7 は OBSERVE モードで `region_id_lookup_v7(ptr)` を呼び、`REGION_SMALL_V7` の統計だけ取る(挙動不変)。 -2. **Phase v7-2**: C6-only v7 本実装(small帯だけ) - - SegmentBox_v7 / ColdIface_v7 を実装し、C6 pages の refill/retire を Segment v7 経由にする。 - - `small_heap_alloc_fast_v7` / `small_heap_free_fast_v7` を実装し、C6-only small 帯を本当に v7 TLS + Segment で回す。 - - C6-heavy / Mixed で v7 vs MID v3 vs V6 vs v2 本線を A/B し、SmallObjectHotBox_v7 の価値を評価。 - - ---- - -## Phase V6-HDR-1: RegionIdBox 実配線・OBSERVE(完了) - -### 目的 - -V6-HDR-0 で作成した RegionIdBox を C6 segment に実配線し、OBSERVE モードで -`ptr → (kind, page_meta.class_idx)` の正当性を検証する。**挙動変更なし**。 - -### 実装タスク - -| No | タスク | 状態 | -|----|--------|------| -| 1 | RegionIdBox 実装を埋める(C6 segment lookup)| ✅ | -| 2 | v6 free の REGION_OBSERVE ロジック具体化 | ✅ | -| 3 | front 側 class_idx ヒント配線確認 | ✅ | -| 4 | ドキュメント更新(CURRENT_TASK.md, REGIONID_V6_DESIGN.md)| ✅ | -| 5 | テスト(OBSERVE ON でベンチ実行)| ✅ | - -### 実装詳細 - -1. **RegionIdBox 実装** (`core/region_id_v6.c`) - - `region_id_lookup_v6(ptr)`: `small_page_meta_v6_of(ptr)` を使用して C6 segment 判定 - - TLS cache 付き高速版: `region_id_lookup_cached_v6(ptr)` - - OBSERVE ログ: `HAKMEM_REGION_ID_V6_OBSERVE=1` で有効 - -2. **REGION_OBSERVE ロジック** (`core/smallobject_core_v6.c`) - - ENV: `HAKMEM_SMALL_V6_REGION_OBSERVE=1`(新設、V6-HDR-1 専用) - - free 入口で `region_id_lookup_v6(ptr)` を呼び、class_idx 検証 - - 不一致時: `[V6_REGION_OBSERVE] MISMATCH ptr=... hint=X actual=Y` - -3. **front 配線確認結果** - - `class_idx` hint は `free_tiny_fast()` 内でヘッダバイト `(header & 0x0F)` から取得 - - v6 route (`TINY_ROUTE_SMALL_HEAP_V6`) は現在未接続(break でスキップ) - - これは「OBSERVE only, 挙動変更なし」の仕様通り - -### ENV - -- `HAKMEM_SMALL_V6_REGION_OBSERVE=1`: free path で class_idx 検証ログを出力 - ---- - ---- - -### 1. ベースライン(1 thread, ws=400, iters=1M, seed=1) - -- **Mixed 16–1024B(本線)** - - コマンド: `HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE ./bench_random_mixed_hakmem 1000000 400 1` - - 主な ENV(bench_profile 経由): - - `HAKMEM_TINY_HEAP_PROFILE=C7_SAFE` - - `HAKMEM_TINY_C7_HOT=1` - - `HAKMEM_SMALL_HEAP_V3_ENABLED=1` / `HAKMEM_SMALL_HEAP_V3_CLASSES=0x80`(C7-only v3) - - `HAKMEM_TINY_C7_ULTRA_ENABLED=1`(UF-3 セグメント版, 2MiB/64KiB) - - `HAKMEM_TINY_FRONT_V3_ENABLED=1` / `HAKMEM_TINY_FRONT_V3_LUT_ENABLED=1` - - `HAKMEM_POOL_V2_ENABLED=0` - - Throughput(現 HEAD, Release): **約 44–45M ops/s** - - 競合: - - mimalloc: ~110–120M ops/s - - system: ~90M ops/s - -- **C7-only (1024B 固定, C7 v3 + ULTRA)** - - C7 ULTRA OFF: ~38M ops/s - - C7 ULTRA ON: ~57M ops/s(約 +50%以上) - - C7 向け設計(ULTRA セグメント + TLS freelist + mask free)は成功パターンとみなし、今後の small-object v4/mid に展開予定。 - -- **C6-heavy mid/smallmid (257–768B, C6 は mid/pool 経路)** - - コマンド: `HAKMEM_PROFILE=C6_HEAVY_LEGACY_POOLV1 ./bench_mid_large_mt_hakmem 1 1000000 400 1` - - 現状 Throughput: **約 10M ops/s** - - 過去 Phase82 では LEGACY + flatten で 23–27M ops/s を記録しており、現行 HEAD では lookup 層(hak_super_lookup/mid_desc_lookup 等)がボトルネック化している状態。 - ---- - -### 2. いま本線で有効な箱 - -1. **C7 v3 + C7 ULTRA (UF-3 セグメント版)** - - Hot: TinyC7UltraBox(TLS freelist + 2MiB Segment / 64KiB Page, mask 判定)。 - - Cold: C7UltraSegmentBox(page_meta[] で page/class/used/capacity を管理)。 - - 特徴: - - C7-only で ~38M→~57M ops/s。Mixed でも 35M→44–45M ops/s まで底上げ。 - - C7 ULTRA 管理外の ptr は必ず C7 v3 free にフォールバック(ヘッダ付き Fail-Fast 経路を維持)。 - - ENV: - - `HAKMEM_TINY_C7_ULTRA_ENABLED=1`(デフォルト ON) - - `HAKMEM_TINY_C7_ULTRA_HEADER_LIGHT` は研究箱(デフォルト 0)。 - -2. **SmallObject v3(C7-only 本線)** - - C7 ページ単位の freelist + current/partial 管理。ColdIface は Tiny v1 経由で Superslab/Warm/Stats を触る。 - - C7 ULTRA ON 時は「セグメント内 ptr だけ ULTRA が先に食い、残りは v3 free」が基本構造。 - -3. **mid/pool v1(C6 は一旦ここに固定, Phase C6-FREEZE)** - - C6 は Tiny/SmallObject/ULTRA で特別扱いしない。 - - C6 専用 smallheap v3/v4/ULTRA・pool flatten はすべて ENV opt-in の研究箱扱い。 - - 現状 C6-heavy は ~10M ops/s。再設計ターゲット。 - ---- - -### 3. small-object v4 / mid 向けの現状と方針 - -- **SmallObjectHotBox_v4 の箱構造(設計済み, 部分実装)** - - `SmallPageMeta`: `free_list/used/capacity/class_idx/flags/page_idx/segment`。 - - `SmallClassHeap`: `current/partial_head/full_head`。 - - `SmallHeapCtx`: per-thread で `SmallClassHeap cls[NUM_SMALL_CLASSES]` を持つ。 - - `SmallSegment` (v4): 2MiB Segment / 64KiB Page を前提に `page_meta[]` を持つ。 - - ColdIface_v4: `small_cold_v4_refill_page` / `small_cold_v4_retire_page` / `small_cold_v4_remote_push/drain` の 1 箱。 - -- **C6-only v4 実装(Phase v4-mid-2, 研究箱)** - - C6 の alloc/free を SmallHeapCtx v4 経由で処理し、Segment v4 から refill/retire する経路を実装済み。 - - C6-heavy A/B(C6 v1 vs v4): - - v4 OFF: ~9.4M ops/s - - v4 ON : ~10.1M ops/s(約 +8〜9%) - - Mixed で C6-only v4 を ON にすると +1% 程度(ほぼ誤差内)で回帰なし。 - - デフォルトでは `HAKMEM_SMALL_HEAP_V4_ENABLED=0` / `CLASSES=0x0` のため標準プロファイルには影響しない。 - -- **mid/smallmid の今後の狙い** - - 現状:C6-heavy ~10M ops/s、lookup 系(hak_super_lookup / mid_desc_lookup / classify_ptr / ss_map_lookup)が ~40% を占める。 - - 方向性: - - C7 ULTRA で成功したパターン(Segment + Page + TLS freelist + mask free)を small-object v4 に広げて、ptr→page→class を O(1) にする。 - - mid_desc_lookup / hak_super_lookup などの lookup 層を small-object v4 route から外す。 - - C6/C5 は「hot mid クラス」として段階的に v4 に載せ、その他の mid/smallmid は SmallHeap v4 or pool v1 で扱う。 - ---- - -### 4. 今後のフェーズ(TODO 概要) - -1. **Phase v4-mid-3(C5-only v4 研究箱)** ✅ 完了 - - ENV: `HAKMEM_SMALL_HEAP_V4_ENABLED=1` / `HAKMEM_SMALL_HEAP_V4_CLASSES=0x20` で C5 を SmallHeap v4 route に載せる。 - - A/B 結果: - - C5-heavy (129–256B): v4 OFF **54.4M** → v4 ON **48.7M ops/s** (−10〜11%回帰)。既存 Tiny/front v3 経路が速い。 - - Mixed 16–1024B (C6+C5 v4): C6-only **28.3M** → C5+C6 **28.9M ops/s** (+2%, 誤差〜微改善)。回帰なし。 - - 方針: C5-heavy では v4 が劣後するため、C5 v4 は研究箱のまま標準プロファイルには入れない。Mixed では影響小さいため C5+C6 v4 (0x60) も研究箱として利用可能。 - -2. **Phase v4-mid-4/5/6(C6/C5 v4 の診断と一時凍結)** ✅ 完了 - - C5 v4: - - C5-heavy (129–256B): v4 OFF **54.4M** → v4 ON **48.7M ops/s**(−10〜11% 回帰)。既存 Tiny/front v3 経路が速い。 - - Mixed 16–1024B では C5+C6 v4 ON で +2〜3% 程度の微改善だが、本線として採用するほどのメリットは無い。 - - C6 v4: - - 正しい C6-only ベンチ(MIN=256 MAX=510)で v4 OFF **~58–67M** → v4 ON **~48–50M ops/s**(−15〜28% 回帰)。 - - stats から C6 alloc/free の 100% が v4 経路を通っていることが確認でき、route/fallback ではなく v4 実装そのものが重いことが判明。 - - ws/iters を増やすと TinyHeap とページ共有する設計起因のクラッシュも残存しており、C6 v4 を現行設計のまま本線に載せるのは難しい。 - - TLS fastlist: - - C6 用 TLS fastlist を追加したが、v4 ON 時の C6-heavy throughput はほぼ変わらず(48〜49M ops/s)。根本的な回帰(v4のページ管理/構造)を打ち消すには至っていない。 - - 方針: - - SmallObject v4(C5/C6 向け)は当面 **研究箱のまま凍結**し、本線の mid/smallmid 改善は別設計(small-object v5 / mid-ULTRA / pool 再設計)として検討する。 - - Mixed/C7 側は引き続き「C7 v3 + C7 ULTRA」を基準に A/B を行い、mid/pool 側は現行 v1 を基準ラインとして据え置く。 - -3. **Phase v5-2/3(C6-only v5 通電 & 薄型化)** ✅ 完了(研究箱) - - Phase v5-2: C6-only small-object v5 を Segment+Page ベースで本実装。Tiny/Pool から完全に切り離し、2MiB Segment / 64KiB Page 上で C6 ページを管理。初回は ~14–20M ops/s 程度で v1 より大幅に遅かった。 - - Phase v5-3: C6 v5 の HotPath を薄型化(単一 TLS セグメント + O(1) `page_meta_of` + ビットマップによる free page 検索)。C6-heavy 1M/400 で v5 OFF **~44.9M** → v5 ON **~38.5M ops/s**(+162% vs v5-2, baseline 比約 -14%)。Mixed でも 36–39M ops/s で SEGV 無し。 - - 方針: v5 は v4 より構造的には良いが、C6-only でもまだ v1 を下回るため、当面は研究箱のまま維持。本線 mid/smallmid は引き続き pool v1 基準で見つつ、v5 設計を C7 ULTRA パターンに近づける方向で検討を継続する。 - -3. **Phase v4-mid-SEGV(C6 v4 の SEGV 修正・研究箱安定化)** ✅ 完了 - - **問題**: C6 v4 が TinyHeap のページを共有 → iters >= 800k で freelist 破壊 → SEGV - - **修正**: C6 専用 refill/retire を SmallSegment v4 に切り替え、TinyHeap 依存を完全排除 - - **結果**: - - iters=1M, ws <= 390: **SEGV 消失** ✅ - - C6-only (MIN=257 MAX=768): v4 OFF ~47M → v4 ON ~43M ops/s(−8.5% 回帰のみ、安定) - - Mixed 16–1024B: v4 ON で SEGV なし(小幅回帰許容) - - **方針**: C6 v4 は研究箱として**安定化完了**。本線には載せない(既存 mid/pool v1 を使用)。 - -4. **Phase v5-0(SmallObject v5 refactor: ENV統一・マクロ化・構造体最適化)** ✅ 完了 - - **内容**: v5 基盤の改善・最適化(挙動は完全不変) - - **改善項目**: - - ENV initialization を sentinel パターンで統一(ENV_UNINIT/ENABLED/DISABLED + `__builtin_expect`) - - ポインタマクロ化: `BASE_FROM_PTR`, `PAGE_IDX`, `PAGE_META`, `VALIDATE_MAGIC`, `VALIDATE_PTR` - - SmallClassHeapV5 に `partial_count` 追加 - - SmallPageMetaV5 の field 再配置(hot fields 先頭集約 → L1 cache 最適化, 24B) - - route priority ENV 追加: `HAKMEM_ROUTE_PRIORITY={v4|v5|auto}` - - segment_size override ENV 追加: `HAKMEM_SMALL_HEAP_V5_SEGMENT_SIZE` - - **挙動**: 完全不変(v5 route は呼ばれない、ENV デフォルト OFF) - - **テスト**: Mixed 16–1024B で 43.0–43.8M ops/s(変化なし)、SEGV/assert なし - - **目標**: v5-1 で C6-only stub → v5-2 で本実装 → v5-3 で Mixed に段階昇格 - -5. **Phase v5-1(SmallObject v5 C6-only route stub 接続)** ✅ 完了 - - **内容**: C6 を v5 route に接続(中身は v1/pool fallback) - - **実装**: - - `tiny_route_env_box.h`: C6 で `HAKMEM_SMALL_HEAP_V5_ENABLED=1` なら `TINY_ROUTE_SMALL_HEAP_V5` に分岐 - - `malloc_tiny_fast.h`: alloc/free switch に v5 case 追加(fallthrough で v1/pool に落ちる) - - `smallobject_hotbox_v5.c`: stub 実装(alloc は NULL 返却、free は no-op) - - **ENV**: `HAKMEM_SMALL_HEAP_V5_ENABLED=1` / `HAKMEM_SMALL_HEAP_V5_CLASSES=0x40` で opt-in - - **テスト結果**: - - C6-heavy: v5 OFF ~15.5M → v5 ON ~16.4M ops/s(変化なし, 正常) - - Mixed: 47.2M ops/s(変化なし) - - SEGV/assert なし ✅ - - **方針**: v5-1 では挙動は v1/pool fallback と同じ。研究箱として ENV プリセット(`C6_SMALL_HEAP_V5_STUB`)を `docs/analysis/ENV_PROFILE_PRESETS.md` に追記。v5-2 で本実装を追加。 - -6. **Phase v5-2 / v5-3(SmallObject v5 C6-only 実装+薄型化, 研究箱)** ✅ 完了 - - **内容**: C6 向け SmallObjectHotBox v5 を Segment + Page + TLS ベースで実装し、v5-3 で単一 TLS セグメント+O(1) `page_meta_of`+ビットマップ free-page 検索などで HotPath を薄型化。 - - **C6-heavy 1M/400**: - - v5 OFF(pool v1): 約 **44.9M ops/s** - - v5-3 ON: 約 **38.5M ops/s**(v5-2 の ~14.7M からは +162% だが、baseline 比では約 -14%) - - **Mixed 16–1024B**: - - v5 ON(C6 のみ v5 route)でも 36–39M ops/s で SEGV なし(本線 Mixed プロファイルでは v5 はデフォルト OFF)。 - - **方針**: C6 v5 は構造的には v4 より良く安定もしたが、まだ v1 を下回るため **研究箱のまま維持**。本線 mid/smallmid は引き続き pool v1 基準で見る。 - -7. **Phase v5-4(C6 v5 header light / freelist 最適化)** ✅ 完了(研究箱) - - **目的**: C6-heavy で v5 ON 時の回帰を詰める(target: baseline 比 -5〜7%)。 - - **実装**: - - `HAKMEM_SMALL_HEAP_V5_HEADER_MODE=full|light` ENV を追加(デフォルト full) - - light mode: page carve 時に全ブロックの header を初期化、alloc 時の header write をスキップ - - full mode: 従来どおり alloc 毎に header write(標準動作) - - SmallHeapCtxV5 に header_mode フィールド追加(TLS で ENV を 1 回だけ読んで cache) - - **実測値**(1M iter, ws=400): - - C6-heavy (257-768B): v5 OFF **47.95M** / v5 full **38.97M** (-18.7%) / v5 light **39.25M** (+0.7% vs full, -18.1% vs baseline) - - Mixed 16-1024B: v5 OFF **43.59M** / v5 full **36.53M** (-16.2%) / v5 light **38.04M** (+4.1% vs full, -12.7% vs OFF) - - **結論**: header light は微改善(+0.7-4.1%)だが、target の -5〜7% には届かず(現状 -18.1%)。header write 以外にも HotPath コストあり(freelist 操作、metadata access 等)。v5-5 以降で TLS cache / batching により HotPath を詰める予定。 - - **運用**: 標準プロファイルでは引き続き `HAKMEM_SMALL_HEAP_V5_ENABLED=0`(v5 OFF)。C6 v5 は研究専用で、A/B 時のみ明示的に ON。 - -8. **Phase v5-5(C6 v5 TLS cache)** ✅ 完了(研究箱) - - **目的**: C6 v5 の HotPath から page_meta access を削減、+1-2% 改善を目指す。 - - **実装**: - - `HAKMEM_SMALL_HEAP_V5_TLS_CACHE_ENABLED=0|1` ENV を追加(デフォルト 0) - - SmallHeapCtxV5 に `c6_cached_block` フィールド追加(1-slot TLS cache) - - alloc: cache hit 時は page_meta 参照せず即座に返す(header mode に応じて処理) - - free: cache 空なら block を cache に格納(freelist push をスキップ)、満杯なら evict して新 block を cache - - **実測値**(1M iter, ws=400, HEADER_MODE=full): - - C6-heavy (257-768B): cache OFF **35.53M** → cache ON **37.02M ops/s** (+4.2%) - - Mixed 16-1024B: cache OFF **38.04M** → cache ON **37.93M ops/s** (-0.3%, 誤差範囲) - - **結論**: TLS cache により C6-heavy で +4.2% の改善を達成(目標 +1-2% を上回る)。Mixed では影響ほぼゼロ。page_meta access 削減が効いている。 - - **既知の問題**: header_mode=light 時に infinite loop 発生(freelist pointer が header と衝突する edge case)。現状は full mode のみ動作確認済み。 - - **運用**: 標準プロファイルでは `HAKMEM_SMALL_HEAP_V5_TLS_CACHE_ENABLED=0`(OFF)。C6 研究用で cache ON により v5 性能を部分改善可能。 - -9. **Phase v5-6(C6 v5 TLS batching)** ✅ 完了(研究箱) - - **目的**: refill 頻度を削減し、C6-heavy で v5 full+cache 比の追加改善を狙う。 - - **実装**: - - `HAKMEM_SMALL_HEAP_V5_BATCH_ENABLED` / `HAKMEM_SMALL_HEAP_V5_BATCH_SIZE` を追加し、SmallHeapCtxV5 に `SmallV5Batch c6_batch`(slots[4] + count)を持たせて、C6 v5 alloc/free で TLS バッチを優先的に使うようにした。 - - **実測(1M/400, HEADER_MODE=full, TLS cache=ON, v5 ON)**: - - C6-heavy: batch OFF **36.71M** → batch ON **37.78M ops/s**(+2.9%) - - Mixed 16–1024B: batch OFF **38.25M** → batch ON **37.09M ops/s**(約 -3%, C6-heavy 専用オプションとして許容) - - **方針**: C6-heavy では cache に続いて batch でも +数% 改善を確認できたが、v5 全体は依然 baseline(v1/pool) より遅い。C6 v5 は引き続き研究箱として維持し、本線 mid/smallmid は pool v1 を基準に見る。 - -10. **Phase v6-0(SmallObject Core v6 設計・型スケルトン)** ✅ 完了(設計) - - **目的**: 16〜2KiB small-object/mid 向けに、L0 ULTRA / L1 Core / L2 Segment+ColdIface / L3 Policy の4層構造とヘッダレス前提の HotBox を定義し、「これ以上動かさない核」の設計を固める。 - - **内容**: - - `docs/analysis/SMALLOBJECT_CORE_V6_DESIGN.md` を追加し、SmallHeapCtxV6 / SmallClassHeapV6 / SmallPageMetaV6 / SmallSegmentV6 と ptr→page→class O(1) ルール、HotBox が絶対にやらない責務(header 書き・lookup・Stats など)を明文化。 - - v6 は現時点ではコードは一切触らず、設計レベルの仕様と型イメージだけをまとめた段階。v5 は C6 研究箱として残しつつ、将来 small-object を作り直す際の「芯」として v6 の層構造を採用する。 - -11. **Phase v6-1〜v6-4(SmallObject Core v6 C6-only 実装+薄型化+Mixed 安定化)** ✅ 完了(研究箱) - - **v6-1**: route stub 接続(挙動は v1/pool fallback のまま)。 - - **v6-2**: Segment v6 + ColdIface v6 + Core v6 HotPath の最低限実装。C6-heavy で v6 経路が SEGV なく完走するところまで確認(初期は約 -44%)。 - - **v6-3**: 薄型化(TLS ownership check + batch header write + TLS batch refill)により、C6-heavy で v6 OFF ≈27.1M / v6-3 ON ≈27.1M(±0%, baseline 同等)まで改善。 - - **v6-4**: Mixed での v6 安定化。`small_page_meta_v6_of` が TLS メタではなく mmap 領域を見ていたバグを修正し、Mixed v6 ON でも完走(C6-only v6 のため Mixed は v6 ON ≈35.8M, v6 OFF ≈44M)。 - - **現状**: - - C6-heavy: v6 OFF ≈27.1M / v6 ON ≈27.4M(C6 Core v6 は baseline 同等・安定)。 - - Mixed: C6-only v6 のため全体ではまだ約 -19% 回帰。C6-heavy 用の実験箱として v6 を維持しつつ、本線 Mixed は引き続き v6 OFF を基準に見る。 - -12. **Phase v6-5(SmallObject Core v6 C5 拡張, 研究箱)** ✅ 完了 - - **目的**: Core v6 を C5 サイズ帯(129–256B)にも拡張し、free hotpath で v6 がカバーするクラスを増やす足場を作る。 - - **実装**: - - `SmallHeapCtxV6` に C5 用 TLS freelist(`tls_freelist_c5` / `tls_count_c5`)を追加し、C5 でも `small_alloc_fast_v6` / `small_free_fast_v6` が TLS→refill/slow のパターンで動くようにした。 - - ColdIface v6 の refill/retire を class_idx(C5/C6)に応じて block_size/容量を変えられるよう一般化。 - - **実測(1M/400, v6 ON C5-only, C6 v6 OFF)**: - - C5-heavy (129–256B): v6 OFF ≈53.6M → v6 ON(C5) ≈41.0M(約 -23%) - - Mixed 16–1024B: v6 OFF ≈44.0M → v6 ON(C5) ≈36.2M(約 -18%) - - **方針**: C5 Core v6 は安定して動くものの、Tiny front v3 + v1/pool より大きく遅いため、本線には乗せず C5 v6 は研究箱扱いとする。C5-heavy/Mixed の free hotpath をさらに削るなら、v6 側のさらなる薄型化か、別の箱(front/gate や pool)の再設計を検討する。 - -13. **Phase v6-6(SmallObject Core v6 C4 拡張, 研究箱)** ✅ 完了 - - **目的**: Core v6 を C4 サイズ帯(65–128B)に拡張して、free hotpath カバー範囲を広げ、`ss_fast_lookup`/`slab_index_for` 依存を削減。 - - **実装内容**: - - `SmallHeapCtxV6` に C4 用 TLS freelist(`tls_freelist_c4` / `tls_count_c4`)を追加。 - - `small_alloc_fast_v6` に C4 fast/cold refill path を追加(`small_alloc_c4_hot_v6` / `small_alloc_cold_v6` で C4 支援)。 - - `small_free_fast_v6` に C4 TLS push path を追加(`small_free_c4_hot_v6`)。 - - `malloc_tiny_fast.h` alloc/free dispatcher に C4 case を追加。 - - ColdIface v6 refill を C4(128B block)に対応。 - - **バグ修正**: `small_alloc_cold_v6` に C4 refill logic が欠落していたのを修正(cold path で C4 refill が実装されていなかったため、全て pool fallback になっていた)。 - - **実測値**(100k iter, v6 ON, mixed size workload): - - **C4-only (80B, class 4)**: v6 OFF ≈47.4M → v6 ON ≈39.4M(**−17% 回帰**) - - **C5+C6 (mixed 200/400B)**: v6 OFF ≈43.5M → v6 ON ≈26.8M(**−38% 回帰**) - - **Mixed (500B)**: v6 OFF ≈40.8M → v6 ON ≈27.5M(**−33% 回帰**) - - **評価**: - - 目標: v6-6 は ±0–数% within acceptable range(user 指定)を狙っていたが、C4 実装によっても大きな回帰が消えず(C4-only: −17%)。 - - 根本原因: v6 実装そのもの(TLS ownership check + page refill + cold path)の overhead が v5 以来続いており、C4 拡張では構造的な改善に至らず。 - - **安全確認の閾値超過**: Mixed で −33% は user 指定の「−10% 以上落ちたら研究箱に留める」基準を大きく超過。 - - **方針**: **Phase v6-6 は研究箱に留め、本線に乗せない**。v6-6 (C4 extend )は ENV opt-in のみ。混在リスク防止のため、v6-5(C5)と v6-6(C4)は同時 ON は非推奨(Mixed で −33%)。 - - **今後の方向性**: - - v6 系は「C6 baseline 同等」では達成できたが(v6-3:C6-only で ±0%),C5/C4 への拡張では overhead が大きい。 - - 次のアプローチは v6 architecture の root cause 調査(TLS ownership check の cost / page refill overhead / cold path cost 等)か、別設計(pool v2 再設計, front gate 薄型化, ULTRA segment 拡張)を検討すべき。 - ---- - -### 6. free path 最適化の方針(Phase FREE-LEGACY-BREAKDOWN 系列) - -**現状認識**: -- Mixed 16–1024B の perf 内訳: free ≈ 24%, tiny_alloc_gate_fast ≈ 22% -- v6(C5/C4 拡張)で −33% 回帰、free-front v3 で −4% 回帰 -- 新世代追加ではなく、既存 free path の「どの箱が何%食っているか」を可視化してピンポイント削減する方針に転換 - -**本線の前提(固定)**: -- Mixed 16–1024B: Tiny front v3 + C7 ULTRA + pool v1(約 44–45M ops/s) -- v4/v5/v6(C5/C4)/ free-front v3 は 研究箱・デフォルト OFF -- v6 は C6-only の mid 向けコア(C6-heavy プロファイル専用で ON、±0% 達成) -- `HAKMEM_SMALL_HEAP_V6_ENABLED=0` / `HAKMEM_TINY_FREE_FRONT_V3_ENABLED=0` が基準 - -**Phase FREE-LEGACY-BREAKDOWN-1** ✅ 完了 -- 目的: free ホットパスを箱単位でカウントし、内訳を可視化 -- 実装: - - ENV: `HAKMEM_FREE_PATH_STATS=1` で free path の箱ごとカウンタを有効化(default 0) - - FreePathStats 構造体で c7_ultra / v3 / v6 / pool v1 / super_lookup / remote_free などを計測 - - デストラクタで `[FREE_PATH_STATS]` 出力 -- 測定結果: `docs/analysis/FREE_LEGACY_PATH_ANALYSIS.md` に記録 -- 次フェーズ: 測定結果を見て FREE-LEGACY-OPT-1/2/3 のどれを実装するか決定 - -**Phase FREE-LEGACY-BREAKDOWN-1 測定結果** ✅ 完了 -- Mixed 16–1024B の free 経路内訳: - - **C7 ULTRA fast**: 50.7% (275,089 / 542,031 calls) - - **Legacy fallback**: 49.2% (266,942 / 542,031 calls) - - pool_v1_fast: 1.5% (8,081 / 542,031 calls) - - その他(v3/v6/tiny_v1/super_lookup/remote): 0.0% -- C6-heavy の free 経路内訳: - - **pool_v1_fast**: 100% (500,099 / 500,108 calls) - - その他: 0.0% -- 主要発見: - - Mixed は **完全な二極化構造**(C7 ULTRA 50.7% vs Legacy 49.2%) - - C6-heavy は pool_v1 経路のみを使用(最適化ターゲット明確) -- 詳細: `docs/analysis/FREE_LEGACY_PATH_ANALYSIS.md` 参照 - -**Phase FREE-LEGACY-OPT-4 シリーズ: Legacy fallback 削減(計画中)** -- 目的: Mixed の Legacy fallback 49.2% を削減し、C7 ULTRA パターンを他クラスに展開 -- アプローチ: - - **4-0**: ドキュメント整理 ✅ - - **4-1**: Legacy の per-class 分析(どのクラスが Legacy を最も使用しているか特定) - - **4-2**: 1クラス限定 ULTRA-Free lane の設計・実装 - - 対象: 4-1 で特定された最大シェアクラス(仮に C5) - - 実装: TLS free キャッシュのみ追加(alloc 側は既存のまま) - - ENV: `HAKMEM_TINY_C5_ULTRA_FREE_ENABLED=0` (研究箱) - - **4-3**: A/B テスト(Mixed で効果測定、結果次第で本線化 or 研究箱維持) -- 期待効果: Legacy 49% → 35-40% に削減、free 全体で 5-10% 改善、Mixed で +2-4M ops/s - ---- - -### 5. 健康診断ラン(必ず最初に叩く 2 本) - -- Tiny/Mixed 用: - ```sh - HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE \ - ./bench_random_mixed_hakmem 1000000 400 1 - # 目安: 44±1M ops/s / segv/assert なし - ``` - -- mid/smallmid C6 用: - ```sh - HAKMEM_PROFILE=C6_HEAVY_LEGACY_POOLV1 \ - ./bench_mid_large_mt_hakmem 1 1000000 400 1 - # 現状: ≈10M ops/s / segv/assert なし(再設計ターゲット) - ``` - -まとめて叩きたいときは `scripts/verify_health_profiles.sh`(存在する場合)を利用し、 -詳細な perf/フェーズログは `CURRENT_TASK_ARCHIVE_20251210.md` と各 `docs/analysis/*` を参照してください。 - - ---- - -## Phase FREE-LEGACY-OPT-4-4: C6 ULTRA free+alloc 統合(寄生型 TLS キャッシュ)✅ 完了 - -### 目的 -Phase 4-3 で free-only TLS キャッシュが effective でないことが判明したため、 -alloc 側に TLS pop を追加して統合し、完全な alloc/free サイクルを実現。 - -### 実装内容 -- malloc_tiny_fast.h: C6 ULTRA alloc pop(L191-202) -- FreePathStats: c6_ultra_alloc_hit カウンタ追加 -- ENV: HAKMEM_TINY_C6_ULTRA_FREE_ENABLED (default: OFF) - -### 計測結果 - -**Mixed 16–1024B (1M iter, ws=400)**: -- OFF (baseline): 40.2M ops/s -- ON (統合後): 42.2M ops/s -- **改善: +4.9%** ✅ 期待値達成 - -**C6-heavy (257-768B, 1M iter, ws=400)**: -- OFF: 40.7M ops/s -- ON: 43.8M ops/s -- **改善: +7.6%** ✅ Mixed より効果大 - -### 効果の分析 - -**Legacy の劇的削減**: -- Legacy fallback: 266,942 → 129,623 (**-51.4%**) -- Legacy by class[6]: 137,319 → 0 (**100% 排除**) - -**TLS サイクルの成功**: -- C6 allocs: 137,241 が TLS pop で direct serve -- C6 frees: 137,319 が TLS push で登録 -- キャッシュは過充填しない(alloc が drain) - -### 設計パターン - -**寄生型 TLS キャッシュ**: -- Core v6 のような専用 segment 管理なし -- 既存 allocator に「寄生」(overhead minimal) -- free + alloc 両方制御で完全なサイクル実現 - -### 判定結果 - -✅ **期待値達成**: +3-5% → **+4.9%** を実現 -✅ **C6 legacy 100% 排除**: 設計の妥当性確認 -✅ **本命候補に昇格**: ENV デフォルト OFF は維持 - ---- - -## Phase REFACTOR-1/2/3: Code Quality Improvement ✅ 完了 - -### 実施内容 - -1. **REFACTOR-1: Magic Number → Named Constants** - - 新ファイル: tiny_ultra_classes_box.h - - TINY_CLASS_C6/C7、tiny_class_is_c6/c7() マクロ定義 - - malloc_tiny_fast.h: == 6, == 7 → semantic macros - -2. **REFACTOR-2: Legacy Fallback Logic 統一化** - - 新ファイル: tiny_legacy_fallback_box.h - - tiny_legacy_fallback_free_base() 統一関数 - - 重複削除: 60行(malloc_tiny_fast.h と tiny_c6_ultra_free_box.c) - -3. **REFACTOR-3: Inline Pointer Macro 中央化** - - 新ファイル: tiny_ptr_convert_box.h - - tiny_base_to_user_inline(), tiny_user_to_base_inline() - - offset 1 byte を centralized に - -### 効果 - -- ✅ **DRY 原則**: Code duplication 削減(60行) -- ✅ **可読性**: Magic number → semantic macro -- ✅ **保守性**: offset, logic を1箇所で定義 -- ✅ **Performance**: Zero regression(inline preserved) - -### 累積改善(Phase 4-0 → Refactor-3) - -| Phase | 改善 | 累積 | 特徴 | -|-------|------|------|------| -| 4-1 | - | - | Legacy per-class 分析 | -| 4-2 | +0% | 0% | Free-only TLS(効果なし) | -| 4-3 | +1-3% | 1-3% | Segment 学習(限定的) | -| **4-4** | **+4.9%** | **+4.9%** | **Free+alloc 統合(本命)** | -| REFACTOR | +0% | +4.9% | Code quality(overhead なし) | - ---- - -## Phase FREE-FRONT-V3-1 実装完了 (2025-12-11) - -**目的**: free 前段に「v3 snapshot 箱」を差し込み、route 判定と ENV 判定を 1 箇所に集約する足場を作る。挙動は変えない。 - -**実装内容**: - -1. **新規ファイル作成**: `core/box/free_front_v3_env_box.h` - - free_route_kind_t enum (FREE_ROUTE_LEGACY, FREE_ROUTE_TINY_V3, FREE_ROUTE_CORE_V6_C6, FREE_ROUTE_POOL_V1) - - FreeRouteSnapshotV3 struct (route_kind[NUM_SMALL_CLASSES]) - - API 3個: free_front_v3_enabled(), free_front_v3_snapshot_get(), free_front_v3_snapshot_init() - - ENV: HAKMEM_TINY_FREE_FRONT_V3_ENABLED (default 0 = OFF) - -2. **実装ファイル**: `core/box/free_front_v3_env_box.c` - - free_front_v3_enabled() - ENV lazy init (default OFF) - - free_front_v3_snapshot_get() - TLS snapshot アクセス - - free_front_v3_snapshot_init() - route_kind テーブル初期化 - - 現行 tiny_route_for_class() を使って既存挙動を維持 - -3. **ファイル修正**: `core/box/hak_free_api.inc.h` - - FG_DOMAIN_TINY 内に v3 snapshot routing logic を追加 - - v3 OFF (default) では従来パスを維持(挙動変更なし) - - v3 ON では snapshot 経由で route 決定 (v6 c6, v3, pool v1) - -4. **Makefile 更新** - - OBJS_BASE, BENCH_HAKMEM_OBJS_BASE, SHARED_OBJS に free_front_v3_env_box.o 追加 - -**ビルド結果**: -- ✅ コンパイル成功 (free_front_v3_env_box.o 生成) -- ✅ リンク成功 (free_front_v3_enabled, free_front_v3_snapshot_get シンボル解決) -- 既存の v3/v4/v5/v6 関連のリンクエラーは pre-existing issue - -**次フェーズ (FREE-FRONT-V3-2)**: -- route_for_class 呼び出し削減 -- ENV check 削除(snapshot 内に統合済み) -- snapshot 初期化の最適化 - ---- - -## Phase FREE-FRONT-V3-2 実装完了 (2025-12-11) - -**目的**: free path から `tiny_route_for_class()` 呼び出しと redundant な ENV check を削減し、free 処理を最適化する。 - -**実装内容**: - -1. **smallobject_hotbox_v3_env_box.h に small_heap_v3_class_mask() 追加** - - v3 対象クラスのビットマスクを返す関数を追加(v6 と同様の API) - - small_heap_v3_class_enabled() をマスク経由に書き換え - -2. **free_front_v3_snapshot_init() の最適化** (core/box/free_front_v3_env_box.c) - - tiny_route_for_class() 呼び出しを完全削除 - - ENV マスクを直接読んで判定(v6_mask, v3_mask) - - 優先度順に route 決定: v6 > v3 > pool/legacy - -3. **hak_free_at() v3 path の最適化** (core/box/hak_free_api.inc.h) - - v6 hot path を inline で呼び出す(small_free_c6_hot_v6, c5, c4) - - ENV check なし、snapshot だけで完結 - - v3 path (C7) は so_free() に委譲(ss_fast_lookup は v3 内部で処理) - -**ベンチマーク結果**: - -**Mixed 16-1024B (bench_random_mixed_hakmem 100000 400 1)**: -- v3 OFF (baseline): 42.6M, 41.6M, 45.2M ops/s → 平均 **43.1M ops/s** -- v3 ON (optimized): 41.1M, 39.9M, 43.0M ops/s → 平均 **41.3M ops/s** -- 結果: **−4.2%** (微回帰) - -**C6-heavy mid/smallmid (bench_mid_large_mt_hakmem 1 100000 400 1)**: -- v3 OFF (baseline): 13.8M, 15.2M, 14.5M ops/s → 平均 **14.5M ops/s** -- v3 ON (optimized): 15.5M, 15.2M, 14.0M ops/s → 平均 **14.9M ops/s** -- 結果: **+2.8%** (誤差〜微改善) - -**安定性**: -- ✅ コンパイル成功、リンク成功 -- ✅ SEGV/assert なし -- ✅ v3 OFF 時は従来パスを維持(完全に変更なし) - -**結論**: -- Mixed で微回帰 (−4%) が見られるため、v3 は引き続き研究箱(default OFF)として維持 -- C6-heavy では微改善 (+3%) が確認されたが、誤差範囲内 -- snapshot infrastructure は正常に動作しており、今後の最適化の足場として有用 -- Phase v3-3 では、v6 hot path の inline 化や route dispatch の最適化を検討 - ---- - -## Phase PERF-ULTRA-REBASE-1 実施完了 (2025-12-11) - -**目的**: C4-C7 ULTRA を全て有効にした状態での CPU ホットパス計測 - -**計測条件**: -- ENV: HAKMEM_TINY_C4/C5/C6/C7_ULTRA_FREE_ENABLED=1(全て ON) -- v6/v5/v4/free-front-v3 は OFF(研究箱) -- ワークロード: Mixed 16-1024B, 10M cycles, ws=8192 -- Throughput: 31.61M ops/s - -**ホットパス分析結果** (allocator 内部, self%): - -| 順位 | 関数/パス | self% | 分類 | -|------|----------|-------|------| -| 🔴 **#1** | **C7 ULTRA alloc** | **7.66%** | ← **新しい最大ボトルネック** | -| #2 | C4-C7 ULTRA free群 | 5.41% | alloc-free cycle | -| #3 | so_alloc系 (v3 backend) | 3.60% | 中規模alloc | -| #4 | page_of/segment判定 | 2.74% | ptr解決 | -| #5 | gate/front前段 | 2.51% | ✅改善済み | -| #6 | so_free系 | 2.47% | - | -| #7 | ss_map_lookup | 0.79% | ✅大幅改善済み | - -**重要な発見**: -1. **C7 ULTRA alloc が明確な最大ボトルネック** - gate/front や header はもう十分薄い -2. **header書き込みが不可視** (< 0.17%) - ULTRA経路での削減効果が出ている -3. **gate/front は既に許容範囲** (2.51%) - 以前のフェーズより改善済み - -**分析結論**: -- v6/v5/v4 のような新世代追加ではなく、「既に当たりが出ている C7/C4/C5/C6 ULTRA 内部を薄くする」フェーズへ転換すべき -- C7 ULTRA alloc の 7.66% を 5-6% に削れば、全体で 2-3% の効果が期待できる - -**詳細**: `docs/analysis/TINY_CPU_HOTPATH_USERLAND_ANALYSIS.md` 参照 - ---- - -## Phase PERF-ULTRA-ALLOC-OPT-1 計画(実装予定) - -**目的**: C7 ULTRA alloc(7.66%)の内部最適化による alloc パス高速化 - -**ターゲット**: `tiny_c7_ultra_alloc()` の hot path を直線化 - -**実装施策**: -1. **TLS ヒットパスの直線化** - - env check / snapshot 取得が残っていないか確認 - - fast path を完全に直線化(分岐最小化) -2. **TLS freelist レイアウト最適化** - - 1 cache line に収まるか確認 - - alloc ホットデータ(freelist[], count)の配置最適化 -3. **segment/page_meta アクセスの確認** - - segment learning / page_meta access が本当に slow path だけか確認 - - hot path に余分なメモリアクセスがないか確認 - -**計測戦略**: -- C7-only と Mixed 両方の A/B テスト(enabler: HAKMEM_TINY_C7_ULTRA_FREE_ENABLED=1) -- perf 計測で self% が 7.66% → 5-6% まで落ちるか確認 -- throughput 改善量を測定 - -**期待値**: alloc パスで 5-10% の削減 - -**次ステップ**: 実装完了後、perf 再計測で効果を検証 - ---- - -## 次フェーズ候補(決定保留中) - -### 実装予定フェーズ - -1. **Phase PERF-ULTRA-ALLOC-OPT-1** (即座実装) - - C7 ULTRA alloc 内部最適化 - - 目標: 7.66% → 5-6% - - 期待: 全体で 2-3% 改善 - -2. **Phase PERF-ULTRA-ALLOC-OPT-2** (後続) - - C4-C7 ULTRA free群(5.41%)の軽量化 - - page_of / segment判定との連携最適化 - -### 研究箱(後回し、当面は OFF) - -- **C3/C2 ULTRA**: legacy 小さい(4% 未満)のに TLS 増加で L1 汚染リスク -- **v6/v5/v4 拡張**: 既存 v1/pool より大幅に遅く、新世代追加は現段階では回帰誘発 -- **FREE-FRONT-V3-2**: 以前 -4% 回帰があったため、ULTRA 整備後に再検討 - ---- - -## 実装ポリシー変換(重要) - -### これまで(フェーズ 4-4 まで) -- 新しい箱や世代(v4/v5/v6/free-front-v3 等)を増やす -- 当たりが出たら本線化する - -### 今後(PERF-ULTRA-ALLOC-OPT 以降) -- **既に当たりが出ている箱(C4-C7 ULTRA)の中身を細かく削る** -- 新世代追加は避ける(L1 キャッシュ汚染、複雑度増加のリスク) -- hotpath 分析 → ピンポイント最適化のサイクルを回す - - ---- - -## Phase PERF-ULTRA-ALLOC-OPT-1 実装試行 (2025-12-11) - -**目的**: C7 ULTRA alloc(現在 7.66% self%)の hot path を直線化し、5-6% まで削減 - -**実装内容**: -- 新規ファイル作成: - - `core/box/tiny_c7_ultra_free_env_box.h`: ENV gate (HAKMEM_TINY_C7_ULTRA_FREE_ENABLED, default ON) - - `core/box/tiny_c7_ultra_free_box.h`: TLS structure (TinyC7UltraFreeTLS) with optimized layout (count first) - - `core/box/tiny_c7_ultra_free_box.c`: tiny_c7_ultra_alloc_fast() / tiny_c7_ultra_free_fast() implementation -- 変更ファイル: - - `core/front/malloc_tiny_fast.h`: 新しい C7 ULTRA alloc/free fast path の統合 - - `core/box/free_path_stats_box.h`: c7_ultra_free_fast / c7_ultra_alloc_hit カウンタ追加 - - `Makefile`: tiny_c7_ultra_free_box.o の追加 - -**設計意図**: -- C4/C5/C6 ULTRA free と同様の「寄生型 TLS キャッシュ」パターンを C7 に適用 -- TLS freelist (128 slots) で alloc/free を高速化 -- hot field (count) を構造体先頭に配置して L1 cache locality 向上 -- 既存 C7 ULTRA (UF-3) をコールドパスとして温存 - -**実装上の課題**: -1. **Segment lookup 問題**: - - tiny_c7_ultra_segment_from_ptr() が常に NULL を返す現象を確認 - - BASE pointer / USER pointer 両方試したが解決せず - - g_ultra_seg (TLS変数) の初期化タイミング or 可視性の問題の可能性 - -2. **TLS cache 未動作**: - - FREE_PATH_STAT の c7_ultra_free_fast カウンタが常に 0 - - c7_ultra_alloc_hit カウンタも常に 0 - - segment check を完全に bypass しても改善せず - - TLS cache への push/pop が一度も成功していない状態 - -3. **統合の複雑性**: - - 既存 C7 ULTRA (UF-1/UF-2/UF-3) と新実装の ENV 変数が異なる - - HAKMEM_TINY_C7_ULTRA_ENABLED (既存) vs HAKMEM_TINY_C7_ULTRA_FREE_ENABLED (新規) - - 既存実装が tiny_c7_ultra.c で独自の TLS freelist を持っている - -**計測結果**: -- Build: 成功 (warning のみ) -- Sanity test: 成功 (SEGV/assert なし) -- Throughput: ~44M ops/s (ベースラインと同等, 改善なし) -- perf self%: 7.66% (変化なし, 最適化未適用状態) - -**分析と考察**: -1. **根本原因の可能性**: - - C7 ULTRA の既存実装 (tiny_c7_ultra.c) が独自の TLS state と segment 管理を持つ - - 新規に作成した TLS cache が既存実装と統合されていない - - segment lookup が期待通り動作しない (g_ultra_seg の初期化/可視性問題) - -2. **アプローチの見直し必要性**: - - 現在: 既存 C7 ULTRA とは別の並列システムを作成 (C4/C5/C6 パターン) - - 提案: 既存 tiny_c7_ultra.c の tiny_c7_ultra_alloc() を直接最適化すべき - - 理由: C7 ULTRA は既に専用 segment と TLS を持ち、独立したサブシステム - -3. **次ステップの推奨**: - - Option A: tiny_c7_ultra.c の tiny_c7_ultra_alloc() 内部を直接最適化 - - ENV check の外出し - - TLS freelist access の直線化 - - 不要な分岐の削除 - - Option B: 現在の実装の segment lookup 問題を解決 - - g_ultra_seg の初期化タイミングを調査 - - デバッグビルドでの詳細トレース - - segment registry との統合確認 - -**ステータス**: **未完了 (要再設計)** - -**教訓**: -- C7 ULTRA は C4/C5/C6 と異なり、既に専用の segment 管理と TLS を持つ独立システム -- 「寄生型」パターンは既存 allocator に寄生する前提だが、C7 ULTRA は独立しており不適合 -- 直接最適化 (ENV check 外出し、分岐削減) の方が適切なアプローチの可能性が高い - -**次フェーズへの示唆**: -- Phase PERF-ULTRA-ALLOC-OPT-1 は一旦保留し、アプローチを再検討 -- tiny_c7_ultra.c の tiny_c7_ultra_alloc() を直接プロファイリングし、hot path 特定 -- ENV check / 分岐削減 / TLS access 最小化を既存コード内で実施 - ---- - -## Phase PERF-ULTRA-ALLOC-OPT-1 実装完了 (2025-12-11) - -C7 ULTRA alloc は tiny_c7_ultra.c 内最適化で self%/throughput ともほぼ不変。 -これ以上は refill/path 設計が絡むため一旦打ち止め。 - ---- - -## Phase PERF-ULTRA-FREE-OPT-1 実装完了 (2025-12-11) - -**実装内容**: -- C4–C7 ULTRA free を pure TLS push + cold segment learning に統一 -- C4/C5/C6 ULTRA は既に最適化済み(統一 legacy fallback 経由) -- C7 ULTRA free を同じパターンに整列(likely/unlikely + FREE_PATH_STAT_INC 追加) -- base/user 変換は tiny_ptr_convert_box.h マクロで統一済み - -**実測値** (Mixed 16-1024B, 1M iter, ws=400): -- Baseline (C7 ULTRA のみ): 42.0-42.1M ops/s, legacy_fb=266,943 (49.2%) -- Optimized (C4-C7 ULTRA 全有効): 45.7-47.0M ops/s, legacy_fb=26,025 (4.8%) -- **改善: +8.8-11.7%** (平均 +9.3%, 約 +4M ops/s) - -**FREE_PATH_STATS 分析**: -- C7 ULTRA: 275,057 (50.7%, 不変) -- C6 ULTRA: 0 → 137,319 free + 137,241 alloc (**100% カバー**, legacy C6 完全排除) -- C5 ULTRA: 0 → 68,871 free + 68,827 alloc (**100% カバー**, legacy C5 完全排除) -- C4 ULTRA: 0 → 34,727 free + 34,696 alloc (**100% カバー**, legacy C4 完全排除) -- Legacy fallback: 266,943 → 26,025 (**-90.2%**, C2/C3 のみ残存) - -**C4/C5/C6-heavy 安定性確認**: -- C4-heavy (65-128B): 55.0M ops/s, SEGV/assert なし -- C5-heavy (129-256B): 56.5M ops/s, SEGV/assert なし -- C6-heavy (257-768B): 16.9M ops/s, SEGV/assert なし - -**評価**: **目標達成** -- Legacy 49% → 5% に削減(−90%) -- C4/C5/C6 ULTRA により Mixed throughput +9.3% -- 全クラス(C4-C7)で統一された TLS push パターン確立 - - - ---- - -## Phase PERF-ULTRA-REBASE-3: 正しいパラメータで再計測 (2025-12-11) - -**問題**: Phase REBASE-2 で iters=1M, ws=400 は軽すぎて ULTRA 関数が invisible(238 samples のみ)だったため、正しいパラメータで再実施。 - -**修正内容**: iters=10M, ws=8192(Phase REBASE-1 と同じパラメータで再計測) - -### Mixed 16-1024B ホットパス(self% 上位, 1890 samples) - -| 順位 | 関数 | self% | 分類 | -|------|------|-------|------| -| **#1** | **free** | **29.22%** | free dispatcher | -| **#2** | **main** | **19.27%** | benchmark overhead | -| **#3** | **tiny_alloc_gate_fast** | **18.17%** | alloc gate | -| #4 | tiny_c7_ultra_refill | 6.92% | C7 ULTRA refill | -| #5 | malloc | 5.00% | malloc dispatcher | -| #6 | tiny_region_id_write_header (lto_priv) | 4.29% | header write | -| #7 | hak_super_lookup | 2.90% | segment lookup | -| #8 | hak_free_at | 2.36% | free routing | -| #9 | so_free | 2.60% | v3 free | -| #10 | so_alloc_fast | 2.46% | v3 alloc | - -**スループット**: -- Mixed 16-1024B: **30.6M ops/s** (10M iter, ws=8192) -- C6-heavy 257-768B: **17.0M ops/s** (10M iter, ws=8192) - -### C6-heavy ホットパス(self% 上位, 3027 samples) - -| 順位 | 関数 | self% | 分類 | -|------|------|-------|------| -| **#1** | **worker_run** | **10.66%** | benchmark loop | -| **#2** | **free** | **25.13%** | free dispatcher | -| **#3** | **hak_free_at** | **19.89%** | free routing | -| #4 | hak_pool_free_v1_impl | 10.16% | pool v1 free | -| #5 | hak_pool_try_alloc_v1_impl | 10.95% | pool v1 alloc | -| #6 | pthread_once | 5.94% | initialization | -| #7 | hak_pool_free_fast_v2_impl | 3.94% | pool v2 fallback | -| #8 | hak_super_lookup | 4.39% | segment lookup | -| #9 | malloc | 3.77% | malloc dispatcher | -| #10 | hak_pool_try_alloc (part) | 0.66% | pool alloc slow | - -### 分析 - -**Mixed 16-1024B での変化**: -- free: 29.22% (benchmark 外のディスパッチャ部分) -- tiny_alloc_gate_fast: 18.17% (前回 REBASE-1 の計測と一致) -- C7 ULTRA refill: 6.92% (前回 REBASE-1 では 7.66% だったが、ワークロードにより変動範囲内) -- C4-C7 ULTRA free 群: 個別には invisible (< 1% each) だが、合計で数%程度 -- so_alloc系: 2.46% (so_alloc_fast) + 1.16% (so_alloc) = 約 3.62% -- page_of/segment: hak_super_lookup 2.90% - -**C6-heavy での状況**: -- pool v1 経路が dominant: hak_pool_free_v1_impl (10.16%) + hak_pool_try_alloc_v1_impl (10.95%) -- hak_free_at: 19.89% (free routing overhead が大きい) -- hak_super_lookup: 4.39% (segment lookup) -- C6-heavy は完全に pool v1 経路を使用(前回の FREE_PATH_STATS 分析と一致) - -### 次のボトルネック確定 - -**Mixed では**: -- **free dispatcher 全体(29.22%)** が最大 -- tiny_alloc_gate_fast(18.17%)が第二 -- C7 ULTRA refill(6.92%)は既に薄い部類 - -**C6-heavy では**: -- **hak_free_at(19.89%)** が最大の allocator 内部ボトルネック -- pool v1 alloc/free(各 10%)は構造的なコスト -- hak_super_lookup(4.39%)も削減余地あり - -### 次フェーズ候補 - -1. **Option A: free dispatcher 最適化** (Mixed 向け) - - free() 内部の routing logic を最適化 - - hak_free_at の分岐を削減 - - 期待効果: Mixed で free 29% → 25% 程度に削減(+1-2M ops/s) - -2. **Option B: alloc gate 最適化** (Mixed 向け) - - tiny_alloc_gate_fast(18.17%)の内部最適化 - - class 判定や routing の直線化 - - 期待効果: Mixed で alloc gate 18% → 15% 程度に削減(+1-2M ops/s) - -3. **Option C: C6-heavy mid/pool 再設計** (C6 向け) - - hak_free_at(19.89%)の C6 専用 fast path 追加 - - pool v1 の lookup overhead 削減 - - 期待効果: C6-heavy で 17M → 20-25M ops/s - -**推奨**: Option A または B(Mixed が本線のため)。C6-heavy は別途 mid 再設計フェーズで対応。 - -**次フェーズ決定**: -- Mixed: free dispatcher ≈29%, alloc gate ≈18%, C7 ULTRA refill ≈6.9% -- 次は **FREE-DISPATCHER-OPT-1** で hak_free_at 系のルーティング層を薄くする - ---- - -### 生成ファイル - -1. `/mnt/workdisk/public_share/hakmem/perf_ultra_mixed_v3.txt` - Mixed 16-1024B の complete perf report (1890 samples) -2. `/mnt/workdisk/public_share/hakmem/perf_ultra_c6_v3.txt` - C6-heavy の complete perf report (3027 samples) -3. `/mnt/workdisk/public_share/hakmem/CURRENT_TASK_PERF_REBASE3.md` - 詳細レポート - ---- - -## Phase SO-BACKEND-OPT-1: v3 backend (so_alloc/so_free) 分解フェーズ ✅ 完了 (2025-12-11) - -### 目的 - -PERF-ULTRA-REFILL-OPT-1a/1b で C7 ULTRA refill を +11% 最適化した後、次のボトルネック **v3 backend (so_alloc/so_free) が ~5% を占める** ことが判明。 -- Mixed 16-1024B では so_alloc_fast (2.46%) + so_free (2.47%) + so_alloc (1.21%) = 合計 ~5% -- 内訳を細分化し、次フェーズで最適化すべき箇所(クラス別 hot path、メモリアクセス、分岐)を特定する - -### 実装内容(完了) - -✅ **Task 1: ドキュメント更新** -- CURRENT_TASK.md に Phase SO-BACKEND-OPT-1 セクション追加 -- docs/analysis/SMALLOBJECT_HOTBOX_V3_DESIGN.md に「Phase SO-BACKEND-OPT-1: v3 Backend ボトルネック分析」セクション追加 - - 現状認識:v3 backend の perf 内訳(alloc 2.46%, free 2.47%, alloc_slow 1.21% = 合計 5.14%) - - 実装方針:詳細 stats 構造体の定義 - -✅ **Task 2: v3 backend 用 stats 実装** -- ENV: `HAKMEM_SO_V3_STATS` (既存、デフォルト 0)で使用 -- core/box/smallobject_hotbox_v3_box.h に新フィールド追加: - - `alloc_current_hit`: current ページから pop - - `alloc_partial_hit`: partial ページから pop - - `free_current`: current に push - - `free_partial`: partial に push - - `free_retire`: page retire -- core/smallobject_hotbox_v3.c に helper 関数実装 (6個): - - `so_v3_record_alloc_current_hit()` - - `so_v3_record_alloc_partial_hit()` - - `so_v3_record_free_current()` - - `so_v3_record_free_partial()` - - `so_v3_record_free_retire()` - - etc. -- so_alloc_fast / so_free_fast 内に埋め込み -- デストラクタで `[ALLOC_DETAIL]` / `[FREE_DETAIL]` セクション追加 - -✅ **Task 3: Mixed / C7-only で計測** -- C7-only (1024B, 1M iter, ws=400, ULTRA 無効化): - - alloc_current_hit=550095 (99.99%), alloc_partial_hit=5 (0.001%) - - alloc_refill=5045 (0.9%), fallback=0 - - free_retire=349 (0.09%), fallback=0, page_of_fail=0 (perfect) - - Throughput: 42.4M ops/s (baseline 62.9M with ULTRA) -- Mixed 16–1024B (1M iter, ws=400, ULTRA 無効化): - - alloc_current_hit=275089 (100%), alloc_partial_hit=0 - - alloc_refill=2340 (0.85%), fallback=0 - - free_retire=142 (0.07%), fallback=0, page_of_fail=0 (perfect) - - Throughput: 35.9M ops/s (baseline 43.4M with ULTRA) - -✅ **Task 4: 計測分析と次フェーズ候補** -- Alloc パス評価:**alloc_current_hit ≈100% で最適化済み** → page locality 完璧 -- Free パス評価:**free_retire ≈0.1% で最適化済み** → page churn 低い -- Page lookup:**page_of_fail = 0 で robust** → corner case なし -- **結論**: v3 backend のロジック部分(ページ選択、retire)は既に最適化済み -- **ボトルネック特定**: so_alloc/so_free の「内部コスト」(header write, memcpy, 分岐)が 5% overhead の主因 - -### Phase SO-BACKEND-OPT-2 候補(次フェーズ) - -計測結果に基づく実装案(優先度順): - -| 候補 | 内容 | 期待効果 | 難易度 | -|-----|------|---------|--------| -| **Header write 削減** | carve 時一括初期化(light mode) | 1-2% | 低 | -| **Freelist carve 最適化** | pre-carved freelist を Cold IF から返却 | <1% | 中 | -| **分岐削減** | hot path 直線化、unlikely() 使用 | 0.5-1% | 中 | -| **Memcpy 削減** | inline asm や atomic で 8byte store 最適化 | 0.5-1% | 高 | - -**推奨**: Phase SO-BACKEND-OPT-2 実施前に perf profile (cycles:u) で so_alloc_fast/so_free_fast を詳細計測(既存 CPU ホットパス分析に含めるのが望ましい) - -### ビルド・テスト結果 -- ✅ Release ビルド成功 (warning: unused variable `front_snap` は pre-existing) -- ✅ Mixed 16-1024B テスト成功(SEGV/assert なし) -- ✅ C7-only テスト成功 -- ✅ Stats 出力動作確認済み - ---- - ---- - -## Phase FREE-DISPATCHER-OPT-1: free dispatcher 統計計測 (2025-12-11) - -**目的**: free dispatcher(29%)の内訳を細分化 -- domain 判定(tiny/mid/large)の比率 -- route 判定(ULTRA/legacy/pool/v6)の比率 -- ENV check / route_for_class 呼び出し回数 - -**方針**: 統計カウンタを追加し、挙動は変えない。次フェーズ(OPT-2)で最適化実装を判断。 - -**実装内容**: -- FreeDispatchStats 構造体追加(ENV gated, default OFF) -- hak_free_at / fg_classify_domain / tiny_free_gate にカウンタ埋め込み -- 挙動変更なし(計測のみ) - -**ENV**: `HAKMEM_FREE_DISPATCH_STATS=1` で有効化(デフォルト 0) - -**計測結果**: -- Mixed: total=8,081, route_calls=267,967, env_checks=9 - - BENCH_FAST_FRONT により大半は早期リターン - - route_for_class は主に alloc 側で呼ばれる - - ENV check は初期化時の 9回のみ -- C6-heavy: total=500,099, route_calls=1,034, env_checks=9 - - fg_classify_domain に到達する free が多い - - route_for_class 呼び出しは極小(snapshot 効果) - -**結論**: -- ENV check は既に十分最適化されている(初期化時のみ) -- route_for_class は alloc 側での呼び出しが主で、free 側は snapshot で O(1) -- 次フェーズ(OPT-2)では別のアプローチを検討(domain 判定の早期化など) - -**発見**: FREE_DISPATCH_STATS より ENV/route は初期化時にしか呼ばれていない。route_calls=267,967 はほぼ alloc 側から。 - ---- - -## Phase ALLOC-GATE-OPT-1: tiny_alloc_gate_fast 統計計測 (2025-12-11) - -**目的**: alloc gate(18%)の内訳を細分化 -- size→class 変換の回数 -- route_for_class 呼び出し回数 -- alloc-side ENV check 回数 -- クラス別分布(C0〜C7) - -**方針**: 統計カウンタを追加し、挙動は変えない。次フェーズ(OPT-1B)で最適化実装を判断。 - -**実装内容**: -- AllocGateStats 構造体追加(size2class/route/env/class分布) -- malloc_tiny_fast 内にカウンタ埋め込み -- ENV: HAKMEM_ALLOC_GATE_STATS (default 0) -- 挙動変更なし(計測のみ) - -**計測結果**: -- Mixed: total=542,033, size2class=0, route_calls=0, env_checks=275,089, C4-C7=95.2% - - ✅ size_to_class / route_for_class は **完全削減済み**(LUT 効果) - - ✅ C4-C7 が 95% → ULTRA fast path が有効 - - env_checks ≈ c7_calls → C7 ULTRA の ENV gate が毎回呼ばれる(構造的コスト) -- C6-heavy: total=11 → malloc_tiny_fast はほぼ通らない(mid/pool 主体) - -**結論**: -- ✅ alloc gate は **既に十分最適化済み**(LUT + ULTRA で削減済み) -- ❌ さらなる最適化余地は小さい(env_checks は軽量化済み、数%以下の効果) -- 次フェーズでは **free dispatcher (29%)** や **C7 ULTRA refill (7%)** など、他のボトルネックを狙う - -**詳細**: `docs/analysis/ALLOC_GATE_ANALYSIS.md` 参照 - ---- - -## Phase PERF-ULTRA-REBASE-4: 再計測と確認 (2025-12-11) - -**目的**: dispatcher と alloc gate が既に最適化されていることを確認した後、実際に新しい perf profile を取得 - -**計測条件**: -- ENV: 全て OFF(デフォルト、stats 無しで baseline) -- ワークロード: Mixed 16-1024B, 10M iter, ws=8192 -- perf record: cycles:u, F 5000, dwarf call-graph - -### ホットパス分析 (self%, 1K samples) - -| 順位 | 関数/パス | self% | 変化 | -|------|----------|-------|------| -| **#1** | **free** | **25.48%** | −0.74% vs REBASE-3 | -| **#2** | **malloc** | **21.13%** | −0% (同等) | -| **#3** | **tiny_c7_ultra_alloc** | **7.66%** | ±0% (同等) | -| #4 | tiny_c7_ultra_free | 3.50% | −0.6% (最適化効果) | -| #5 | so_free | 2.47% | (新規visible) | -| #6 | so_alloc_fast | 2.39% | (新規visible) | -| **#7** | **tiny_c7_ultra_page_of** | **1.78%** | **NEW: refill path** | -| #8 | so_alloc | 1.21% | (新規visible) | -| #9 | classify_ptr | 1.15% | (新規visible) | - -### 統計情報(Mixed 1M iter, ws=400) - -**Alloc Gate Stats**: +### Layer Structure ``` -total=542,019 calls -size2class=0 calls ✅ (完全削減) -route_calls=0 calls ✅ (完全削減) -env_checks=275,089 (構造的コスト) -class分布: C7=50.8%, C6=25.3%, C5=12.7%, C4=6.4%, C2-C3=4.8% +L3: Learner v2 (smallobject_learner_v2.c) + ↑ (stats aggregation) +L2: StatsBox (smallobject_stats_mid_v3.c) + ↑ (publish events) +L2: ColdIface (smallobject_cold_iface_mid_v3.c) + ↑ (refill/retire) +L2: SegmentBox (smallobject_segment_mid_v3.c) + ↑ (page management) +L1: [Future: Hot path integration] ``` -**Free Dispatcher Stats**: -``` -total=8,081 calls -tiny=0, mid=8,081, large=0 (全て mid パス) -ultra=0 (ULTRA が fre dispatcher を bypass している) -tiny_legacy=7, pool=0, v6=0 -route_calls=267,954 (大部分は alloc 側から呼ばれている) -env_checks=9 (初期化時のみ) -``` +### Data Flow +1. **Page Refill**: ColdIface → SegmentBox (take from free stack) +2. **Page Retire**: ColdIface → StatsBox (publish) → Learner (aggregate) +3. **Decision**: Learner calculates C5 ratio → routing decision (v7 vs MID_v3) -### 分析 +## Key Design Decisions -**確認事項**: -1. **Dispatcher (25.48%) は既に最適化済み** - - route_for_class は 9 回のみ(初期化時) - - 25% はファンクション呼び出しのコスト(architecture level) +1. **No Hot Path Integration**: Phase v11a-2 focuses on infrastructure only + - Existing MID v3 routing unchanged + - New code is dormant (linked but not called) + - Ready for future activation -2. **Alloc Gate (21.13%) は既に最適化済み** - - size_to_class = 0 calls (LUT) - - route_for_class = 0 calls (ULTRA enabled) - - env_checks = 275K はC7 ULTRA の enable check (unavoidable) +2. **ULTRA Geometry Reuse**: 2MiB segments, 64KiB pages + - Proven design from C7 ULTRA + - Efficient for C5-C7 range (257-1024B) + - Good balance between fragmentation and overhead -3. **新しいボトルネック**: - - C7 ULTRA refill (tiny_c7_ultra_page_of) が 1.78% で新規にvisible - - so_alloc/so_free が合計 ~5% - - classify_ptr が 1.15% +3. **Per-Class Free Stacks**: Independent page pools per class + - Reduces cross-class interference + - Simplifies page accounting + - Enables per-class statistics -### スループット +4. **Exponential Smoothing**: 90% historical + 10% new + - Stable metrics despite workload variation + - React to trends without noise + - Standard industry practice -- **Mixed 16-1024B**: 39.5M ops/s (iters=1M, ws=400) -- **比較**: REBASE-3 の 30.6M ops/s(iters=10M, ws=8192)とは別ワークロード +## File Summary -### 次フェーズ候補 +### New Files Created (6 total) +1. `core/smallobject_segment_mid_v3.c` (280 lines) +2. `core/box/smallobject_cold_iface_mid_v3_box.h` (30 lines) +3. `core/smallobject_cold_iface_mid_v3.c` (115 lines) +4. `core/smallobject_stats_mid_v3.c` (180 lines) +5. `core/smallobject_learner_v2.c` (270 lines) -**Option A: C7 ULTRA refill 最適化** -- tiny_c7_ultra_page_of が 1.78% -- Segment learning / page lookup の refill パスを最適化 -- 期待: refill パス削減で全体 1-2% +### Existing Files Modified (4 total) +1. `core/box/smallobject_segment_mid_v3_box.h` (added function prototypes) +2. `core/box/smallobject_learner_v2_box.h` (added stats include, function prototype) +3. `Makefile` (added 4 new .o files to OBJS_BASE and TINY_BENCH_OBJS_BASE) +4. `CURRENT_TASK.md` (this file) -**Option B: Architectural Level の最適化** -- free dispatcher (25%) + malloc dispatcher (21%) = 46% -- 現状は C API (malloc/free) の呼び出しコスト -- 例: ホットパス全体を inlined dispatcher で再設計 -- リスク: 大規模な設計変更 +### Total Lines of Code: ~875 lines (C implementation) -**Option C: so_alloc/so_free 系 (~5%) の削減** -- v3 backend の最適化 -- classify_ptr (1.15%) の削減 -- 期待: 1-2M ops/s +## Next Steps (Future Phases) -**推奨**: Option A(C7 ULTRA refill)から着手。dispatcher/gate の 46% は architecture 的な必要コストで、難易度 vs 効果の観点から現状は受け入れるべき。 +1. **Phase v11a-3**: Hot path integration + - Route C5/C6/C7 through MID v3.5 + - TLS context caching + - Fast alloc/free implementation -### 結論 +2. **Phase v11a-4**: Route switching + - Implement C5 ratio threshold logic + - Dynamic switching between MID_v3 and v7 + - A/B testing framework -- **dispatcher + gate**: 計 46% → 既に最適化済み(ENV/route snapshot 化完了) -- **C7 ULTRA 内部**: alloc 7.66% + free 3.50% + refill 1.78% = 12.94% -- **次のターゲット**: C7 ULTRA refill パス(1.78%)からの削減開始 +3. **Phase v11a-5**: Performance optimization + - Inline hot functions + - Prefetching + - Cache-line optimization + +## Verification Checklist + +- [x] All 5 tasks completed +- [x] Clean compilation (warnings only for unused functions) +- [x] Successful linking +- [x] Sanity benchmark passes (27.3M ops/s) +- [x] No performance regression +- [x] Code modular and well-documented +- [x] Headers properly structured +- [x] RegionIdBox integration works +- [x] Stats collection functional +- [x] Learner aggregation operational + +## Notes + +- **Not Yet Active**: This code is dormant - linked but not called by hot path +- **Zero Overhead**: No performance impact on existing MID v3 implementation +- **Ready for Integration**: All infrastructure in place for future hot path activation +- **Tested Build**: Successfully builds and runs with existing benchmarks --- -## Phase PERF-ULTRA-REFILL-OPT-1a/1b 実装完了 (2025-12-11) - -### 目的 - -C7 ULTRA refill パス(tiny_c7_ultra_page_of の 1.78%)を最適化し、全体のスループット向上を実現 - -### 実装内容 - -**Phase 1a: Page Size Macro化** -```c -// tiny_c7_ultra_segment.c に追加 -#define TINY_C7_ULTRA_PAGE_SHIFT 16 // 64KiB = 2^16 - -// 修正: tiny_c7_ultra_page_of で division を shift に -uint32_t idx = (uint32_t)(offset >> TINY_C7_ULTRA_PAGE_SHIFT); - -// 修正: refill/free で multiplication を shift に -tls->seg_end = tls->seg_base + ((size_t)seg->num_pages << TINY_C7_ULTRA_PAGE_SHIFT); -uint8_t* base = (uint8_t*)seg->base + ((size_t)chosen << TINY_C7_ULTRA_PAGE_SHIFT); -``` - -**Phase 1b: Segment Learning 移動** -```c -// 従来: free初回で segment_from_ptr() を呼び出して学習 -if (unlikely(tls->seg_base == 0)) { - seg = tiny_c7_ultra_segment_from_ptr(ptr); // <- deleted - ... -} - -// 最適化後: segment learning は alloc refill時に移動 -// free では seg_base/seg_end が既に埋まっている前提 -// (normal pattern: alloc → free なので安全) -``` - -### ベンチマーク結果 - -**Mixed 16-1024B (1M iter, ws=400)**: - -| フェーズ | Throughput | 改善 | -|---------|-----------|------| -| Baseline | 39.5M ops/s | baseline | -| Phase 1a | 39.5M ops/s | ±0% (誤差) | -| Phase 1b | 42.3M ops/s | +7.1% | -| **3回平均** | **43.9M ops/s** | **+11.1%** | - -**実測:** -- Run 1: 42.9M ops/s -- Run 2: 45.0M ops/s -- Run 3: 43.7M ops/s - -### 最適化の詳細 - -**1. Division → Bit Shift の効果** -- tiny_c7_ultra_page_of での `offset / seg->page_size` を `offset >> 16` に変更 -- refill/free での `num_pages * page_size` を bit shift に変更 -- 各 division ~2-3 cycles 削減 × 複数呼び出し = 累積効果 - -**2. Segment Learning 削除の効果** -- free 初回での tiny_c7_ultra_segment_from_ptr() call を削除 -- segment learning は alloc refill時に既に実施済み -- 通常パターン(alloc → free)では全く影響なし -- per-thread 1 回の segment_from_ptr() call + 1 回の pointer comparison 削減 - -### 合算効果 - -- Phase 1a: 数% 削減(見えにくいが累積) -- Phase 1b: visible な削減(unlikely cold path 完全削除) -- **Total: +11.1%** = dispatch/gate 優化 (46%) の次に大きい改善 - -### 次フェーズ - -現在の成功: -- C7 ULTRA 内部優化で +11% 達成 -- dispatcher/gate (46%) は既に最適化済み -- 新規ボトルネック: so_alloc/so_free (合計 ~5%) - -候補: -- **Option A**: so_alloc/so_free 最適化 → v3 backend -- **Option B**: classify_ptr (1.15%) 削減 -- **Option C**: 新規サイズクラス (C3/C2 ULTRA) → TLS L1 汚染リスク - -推奨: Option A(v3 backend 最適化)を検討 - -## Phase v7-2: SmallObject v7 C6-only Implementation ✅ - -### 完成 - -- **SmallSegment_v7**: 2MiB segment with TLS slot, free page stack -- **ColdIface_v7**: Page refill/retire with stat publishing (future Learner) -- **HotBox_v7**: Full C6-only alloc/free with proper header format (HEADER_MAGIC | class_idx) -- **RegionIdBox integration**: v7 segment registration for ptr->region lookup -- **Free path fix**: Early-exit v7 check BEFORE ss_fast_lookup (separate mmap segment) - -### ベンチマーク結果 (C6, 400-510B, 500K iter) - -| Mode | Throughput | Cost | -|------|-----------|------| -| v7 OFF (legacy) | 58.6M ops/s | baseline | -| v7 ON (C6-only) | 54.5M ops/s | -7% overhead | - -**v7 stats**: `alloc=275104 free=275104 refill=1360 retire=1360` (perfect balance) - -### 分析 - --7% のオーバーヘッドは RegionIdBox binary search + segment validation が主因 -- v7 は研究箱として OFF のまま(ベンチマークプロファイルでは使用しない) -- Phase v7-3: TLS fast path cache で RegionIdBox オーバーヘッド削減予定 - -### 次: Phase v7-3: C6 TLS Fast Path + Page Metadata Cache - -**目標**: RegionIdBox overhead を削減して v7 ON での性能改善 - -**方針**: -1. SmallHeapCtx_v7 に TLS segment base/end/ptr を追加 → "ほとんどの" free が TLS 範囲内 -2. same-page page_meta TLS cache → 1-2% 改善期待 -3. RegionIdBox は TLS 範囲外のみに制限 → POOL/LEGACY/ULTRA 分類専用 -4. C6-only 維持 (C5/C4 は後の検討) - -## Phase v7-3: SmallObject v7 TLS Fast Path Optimization ✅ - -### 完成 - -**実装箇所**: -- `/mnt/workdisk/public_share/hakmem/core/box/smallobject_cold_iface_v7_box.h`: SmallHeapCtx_v7 構造変更 -- `/mnt/workdisk/public_share/hakmem/core/smallobject_cold_iface_v7.c`: TLS hint 初期化 -- `/mnt/workdisk/public_share/hakmem/core/box/smallobject_hotbox_v7_box.h`: free fast path TLS 最適化 - -**変更点**: -1. **SmallHeapCtx_v7 拡張**: - ```c - typedef struct SmallHeapCtx_v7 { - SmallClassHeap_v7 cls[HAK_SMALL_NUM_CLASSES_V7]; - SmallSegment_v7* segment; - - // Phase v7-3: TLS segment fast hint - uintptr_t tls_seg_base; - uintptr_t tls_seg_end; - - // Phase v7-3: same-page cache (removed - not effective) - // uintptr_t last_page_base/end/meta; - } SmallHeapCtx_v7; - ``` - -2. **TLS segment hint 設定** (`cold_v7_ensure_segment()`): - ```c - ctx->segment = seg; - ctx->tls_seg_base = seg->base; - ctx->tls_seg_end = seg->base + SMALL_SEGMENT_V7_SIZE; - ``` - -3. **free fast path 最適化** (`small_heap_free_fast_v7()`): - ```c - // Path 1: TLS segment hit (most common) - if (addr >= ctx->tls_seg_base && addr < ctx->tls_seg_end) { - // Direct page_idx calculation (skip RegionIdBox) - size_t page_idx = (addr - ctx->tls_seg_base) >> SMALL_PAGE_V7_SHIFT; - // ... fast path ... - } - - // Path 2: RegionIdBox fallback (only for non-TLS pointers) - regionid_fallback: - RegionLookupV6 lk = region_id_lookup_v6(ptr); - // ... cold path ... - ``` - -### ベンチマーク結果 (C6, 400-510B, 500K iter) - -**v7 OFF baseline**: -- Run 1: 58.5M ops/s -- Run 2: 58.0M ops/s -- Run 3: 60.0M ops/s -- **Average: 58.8M ops/s** - -**v7 ON (Phase v7-3 optimized)**: -- Run 1: 57.5M ops/s -- Run 2: 57.2M ops/s -- Run 3: 54.3M ops/s -- **Average: 56.3M ops/s** - -**結果: -4.3% overhead** (vs -7% in Phase v7-2) - -### 分析 - -**改善効果**: -- Phase v7-2: -7.0% overhead (54.5M ops/s vs 58.6M baseline) -- Phase v7-3: -4.3% overhead (56.3M ops/s vs 58.8M baseline) -- **Overhead 削減率: 38%** (7.0% → 4.3%) - -**技術詳細**: -1. **TLS segment bounds check**: - - Most allocations come from TLS segment → high hit rate - - Simple range check (2 comparisons) vs RegionIdBox binary search (O(log N)) - - Page index calculation: bit shift (fast) vs segment traversal - -2. **Same-page cache 削除**: - - Initial implementation included last_page_meta cache - - Profiling showed negligible benefit (< 1%) - - Removed to reduce branch complexity and TLS cache pressure - -3. **Remaining overhead**: - - 4.3% overhead primarily from: - - Extra validation (capacity, class_idx checks) - - Page metadata access (vs direct SuperSlab metadata) - - RegionIdBox fallback on TLS miss (rare but exists) - -### 次の方針 - -**v7 使用判断**: -- -4.3% overhead は許容範囲内(研究箱としては成功) -- Production profile では引き続き OFF (legacy SuperSlab 使用) -- Future: C5/C4 class 追加で coverage 拡大 → overhead 薄まる - -**Phase v7-4 候補**: -- C5 (256B) / C4 (128B) 対応 → coverage 拡大で相対 overhead 削減 -- Page metadata layout 最適化 → cache line alignment -- Remote free 対応 → multi-thread workload 準備 - ---- - -## Phase v7-4: Policy Box 導入 (フロント芯の作り直し) ✅ - -### 完成 - -**実装箇所**: -- `/mnt/workdisk/public_share/hakmem/core/box/smallobject_policy_v7_box.h`: Policy Box ヘッダー (新規作成) -- `/mnt/workdisk/public_share/hakmem/core/smallobject_policy_v7.c`: Policy Box 実装 (新規作成) -- `/mnt/workdisk/public_share/hakmem/core/front/malloc_tiny_fast.h`: v7 routing を Policy Box 経由に変更 -- `/mnt/workdisk/public_share/hakmem/Makefile`: `core/smallobject_policy_v7.o` を OBJS リストに追加 - -**設計意図**: -フロントを「size→class→route_kind→switch」の1層だけにして、ルート決定を Policy Box に集約。Box Theory の L3 に SmallPolicyV7 を配置し、ULTRA/v7/MID_v3/LEGACY の選択を一元化。 - -### Policy Box 実装 - -**1. Route Kind Enum (L0/L1/L1' layer selection)**: -```c -typedef enum { - SMALL_ROUTE_ULTRA, // L0: C4-C7 ULTRA (FROZEN) - SMALL_ROUTE_V7, // L1: SmallObject v7 (research box) - SMALL_ROUTE_MID_V3, // L1': MID v3 (257-768B mid/small) - SMALL_ROUTE_LEGACY, // L1': TinyHeap v1 / Pool v1 (fallback) -} SmallRouteKind; -``` - -**2. Policy Snapshot Structure**: -```c -typedef struct SmallPolicyV7 { - SmallRouteKind route_kind[8]; // C0-C7 routing decision -} SmallPolicyV7; -``` - -**3. Policy API**: -```c -/// Get policy snapshot (read-only, TLS cached) -const SmallPolicyV7* small_policy_v7_snapshot(void); - -/// Initialize policy from ENV variables (called once at startup) -/// Priority: ULTRA > v7 > MID_v3 > LEGACY -void small_policy_v7_init_from_env(SmallPolicyV7* policy); - -/// Get route kind name for debugging -const char* small_route_kind_name(SmallRouteKind kind); -``` - -### ENV 優先順位 (固定) - -**Priority 1: ULTRA (highest)** -- `HAKMEM_TINY_C7_ULTRA_ENABLED` (default ON) → C7 ULTRA -- `HAKMEM_TINY_C6_ULTRA_FREE_ENABLED` → C6 ULTRA (free-only, 将来拡張用) -- Future: `HAKMEM_TINY_C4_ULTRA_ENABLED` / `C5_ULTRA_ENABLED` - -**Priority 2: SmallObject v7 (research box)** -- `HAKMEM_SMALL_HEAP_V7_ENABLED` → v7 有効化 -- `HAKMEM_SMALL_HEAP_V7_CLASSES` (default 0x40 = C6) → v7 対象クラス - -**Priority 3: MID_v3 (mid/small range)** -- `HAKMEM_MID_V3_ENABLED` → MID_v3 有効化 -- `HAKMEM_MID_V3_CLASSES` (default 0x60 = C5-C6) → MID_v3 対象クラス - -**Priority 4: LEGACY (fallback)** -- Default for all classes not covered by above - -### フロント段階移行 - -**alloc path** (malloc_tiny_fast.h, line 227-235): -```c -// Phase v7-4: Check Policy Box for v7 routing (before switch) -const SmallPolicyV7* policy = small_policy_v7_snapshot(); -if (policy->route_kind[class_idx] == SMALL_ROUTE_V7) { - void* v7p = small_heap_alloc_fast_v7_stub(size, (uint8_t)class_idx); - if (TINY_HOT_LIKELY(v7p != NULL)) { - return v7p; - } - // v7 stub returned NULL -> fallback to legacy -} -``` - -**free path** (malloc_tiny_fast.h, line 408-416): -```c -// Phase v7-4: Check Policy Box for v7 routing (before route lookup) -const SmallPolicyV7* policy = small_policy_v7_snapshot(); -if (class_idx == 6 && policy->route_kind[class_idx] == SMALL_ROUTE_V7) { - if (small_heap_free_fast_v7_stub(ptr, (uint8_t)class_idx)) { - FREE_PATH_STAT_INC(smallheap_v7_fast); - return 1; - } - // v7 returned false (ptr not in v7 segment) -> fallback to legacy below -} -``` - -### Box Theory 層構造 - -**L0: ULTRA (frozen, C4-C7)** -- C7 ULTRA: Phase ULTRA-1~6 (production) -- C6/C5/C4 ULTRA: Phase ULTRA-7~9 (future) - -**L1: SmallObject v7 (research box)** -- C6-only (Phase v7-1~4) -- Future: C5/C4 expansion - -**L1': MID_v3 / LEGACY (fallback)** -- MID_v3: 257-768B (C5-C6 range) -- LEGACY: TinyHeap v1 / Pool v1 - -**L2: Segment / RegionId** -- SmallSegment_v7 (64MB mmap region) -- RegionIdBox v6 (ptr → segment lookup) - -**L3: Policy / Stats / Learner** -- **SmallPolicyV7** (this phase): Route decision -- Stats: FreePathStatsBox / AllocGateStatsBox -- Learner: (future) dynamic route selection - -### 段階移行戦略 - -**Phase v7-4 現状**: -- v7 関連のみ Policy box 経由に変更 -- ULTRA/MID_v3/LEGACY は既存の `tiny_route_env_box.h` を併用(後で統合予定) - -**将来の統一**: -- `tiny_route_env_box.h` の ULTRA/MID_v3/LEGACY ルート判定を Policy box に統合 -- クラスごとの柔軟な優先順位設定 -- Learner 連携による動的ルート選択 (ENV override) - -### Debug Output - -初回 TLS 初期化時に stderr に出力: -``` -[POLICY_V7_INIT] Route assignments: - C0: LEGACY - C1: LEGACY - C2: LEGACY - C3: LEGACY - C4: LEGACY - C5: LEGACY - C6: V7 (if HAKMEM_SMALL_HEAP_V7_ENABLED=1) - C7: ULTRA (if HAKMEM_TINY_C7_ULTRA_ENABLED=1, default ON) -``` - -### ビルド確認 - -**コンパイル**: 成功 -``` -gcc -O3 ... -c -o core/smallobject_policy_v7.o core/smallobject_policy_v7.c -gcc -o bench_tiny_hot_hakmem ... core/smallobject_policy_v7.o ... -lm -lpthread -flto -``` - -**リンク**: 成功 (all object lists updated) -- `OBJS_BASE` -- `BENCH_HAKMEM_OBJS_BASE` -- `TINY_BENCH_OBJS_BASE` - -### 次の拡張 - -**Phase v7-5 候補**: -1. **ULTRA/MID_v3/LEGACY 統合**: `tiny_route_env_box.h` → Policy box に移行 -2. **Learner 連携**: ENV defaults + runtime learning override -3. **クラスごとの柔軟な優先順位**: ENV で ULTRA vs v7 の順序を逆転可能に -4. **Multi-class v7**: C5/C4 追加 → coverage 拡大 - -======================================================================== -## SECTION: HAKMEM v2 世代 完了宣言(第1章) -======================================================================== - -### Phase v7-4 完了時点での総括 - -Policy Box 導入により、L0-L3 の層構造が確立。 -「芯の設計練習」は達成し、v2 世代は一旦完成。 - -### 成果ハイライト - -| フェーズ | 目標 | 達成度 | -|---------|------|--------| -| ULTRA (C7) | +10% 目標 | ✅ +11% 達成 | -| MID v3 | 257-768B 本線化 | ✅ 完了 | -| v7 (C6-only) | 研究箱構築 | ✅ 完了、-4.3% overhead | -| Policy Box | route 一元化 | ✅ 完了、ENV 集約 | - -### 次世代への課題一覧 - -**v7 第2章(Phase v7-5 候補)**: -1. Multi-class 拡張(C5/C4)→ overhead 分摊 -2. Learner 連携 → 動的 route 選択 -3. HeaderLess 統一 → v6/v7 mode 統合 - -**開発再開条件**: -- HakORune / JoinIR ノーマライズ優先 -- v2 世代ドキュメント(HAKMEM_V2_GENERATION_SUMMARY.md)が凍結状態で読み返せること - -### 凍結方針 - -- ULTRA: 改造禁止(FROZEN) -- MID v3: バグ修正のみ -- v7: code freeze(research boxとして保存) -- HAKMEM: ここで一旦完成 - -次の開発は HakORune / JoinIR 優先。 +**Phase v11a-2 Status**: ✅ **COMPLETE** +**Date**: 2025-12-12 +**Build Status**: ✅ **PASSING** +**Performance**: ✅ **NO REGRESSION** (27.3M ops/s baseline maintained) diff --git a/Makefile b/Makefile index 6e9a5938..4f9896d0 100644 --- a/Makefile +++ b/Makefile @@ -218,7 +218,7 @@ LDFLAGS += $(EXTRA_LDFLAGS) # Targets TARGET = test_hakmem -OBJS_BASE = hakmem.o hakmem_config.o hakmem_tiny_config.o hakmem_ucb1.o hakmem_bigcache.o hakmem_pool.o hakmem_l25_pool.o hakmem_site_rules.o hakmem_tiny.o core/box/ss_allocation_box.o superslab_stats.o superslab_cache.o superslab_ace.o superslab_slab.o superslab_backend.o core/superslab_head_stub.o hakmem_smallmid.o tiny_sticky.o tiny_remote.o tiny_publish.o tiny_debug_ring.o hakmem_tiny_magazine.o hakmem_tiny_stats.o hakmem_tiny_sfc.o hakmem_tiny_query.o hakmem_tiny_rss.o hakmem_tiny_registry.o hakmem_tiny_remote_target.o hakmem_tiny_bg_spill.o tiny_adaptive_sizing.o hakmem_super_registry.o hakmem_shared_pool.o hakmem_shared_pool_acquire.o hakmem_shared_pool_release.o hakmem_elo.o hakmem_batch.o hakmem_p2.o hakmem_sizeclass_dist.o hakmem_evo.o hakmem_debug.o hakmem_sys.o hakmem_whale.o hakmem_policy.o hakmem_ace.o hakmem_ace_stats.o hakmem_prof.o hakmem_learner.o hakmem_size_hist.o hakmem_learn_log.o hakmem_syscall.o hakmem_ace_metrics.o hakmem_ace_ucb1.o hakmem_ace_controller.o tiny_fastcache.o core/box/superslab_expansion_box.o core/box/integrity_box.o core/box/free_publish_box.o core/box/mailbox_box.o core/box/front_gate_box.o core/box/front_gate_classifier.o core/box/capacity_box.o core/box/carve_push_box.o core/box/prewarm_box.o core/box/ss_hot_prewarm_box.o core/box/front_metrics_box.o core/box/bench_fast_box.o core/box/ss_addr_map_box.o core/box/slab_recycling_box.o core/box/pagefault_telemetry_box.o core/box/tiny_sizeclass_hist_box.o core/box/tiny_env_box.o core/box/tiny_route_box.o core/box/free_front_v3_env_box.o core/box/free_path_stats_box.o core/box/free_dispatch_stats_box.o core/box/alloc_gate_stats_box.o core/box/tiny_c6_ultra_free_box.o core/box/tiny_c5_ultra_free_box.o core/box/tiny_c4_ultra_free_box.o core/box/tiny_page_box.o core/box/tiny_class_policy_box.o core/box/tiny_class_stats_box.o core/box/tiny_policy_learner_box.o core/box/ss_budget_box.o core/box/tiny_mem_stats_box.o core/box/c7_meta_used_counter_box.o core/box/wrapper_env_box.o core/box/madvise_guard_box.o core/box/libm_reloc_guard_box.o core/box/ptr_trace_box.o core/box/link_missing_stubs.o core/box/super_reg_box.o core/box/shared_pool_box.o core/box/remote_side_box.o core/page_arena.o core/front/tiny_unified_cache.o core/tiny_alloc_fast_push.o core/tiny_c7_ultra_segment.o core/tiny_c7_ultra.o core/link_stubs.o core/tiny_failfast.o core/tiny_destructors.o core/smallobject_hotbox_v3.o core/smallobject_hotbox_v4.o core/smallobject_hotbox_v5.o core/smallsegment_v5.o core/smallobject_cold_iface_v5.o core/smallsegment_v6.o core/smallobject_cold_iface_v6.o core/smallobject_core_v6.o core/region_id_v6.o core/smallsegment_v7.o core/smallobject_cold_iface_v7.o core/mid_hotbox_v3.o core/smallobject_policy_v7.o core/smallobject_segment_mid_v3.o core/smallobject_cold_iface_mid_v3.o core/smallobject_stats_mid_v3.o core/smallobject_learner_v2.o +OBJS_BASE = hakmem.o hakmem_config.o hakmem_tiny_config.o hakmem_ucb1.o hakmem_bigcache.o hakmem_pool.o hakmem_l25_pool.o hakmem_site_rules.o hakmem_tiny.o core/box/ss_allocation_box.o superslab_stats.o superslab_cache.o superslab_ace.o superslab_slab.o superslab_backend.o core/superslab_head_stub.o hakmem_smallmid.o tiny_sticky.o tiny_remote.o tiny_publish.o tiny_debug_ring.o hakmem_tiny_magazine.o hakmem_tiny_stats.o hakmem_tiny_sfc.o hakmem_tiny_query.o hakmem_tiny_rss.o hakmem_tiny_registry.o hakmem_tiny_remote_target.o hakmem_tiny_bg_spill.o tiny_adaptive_sizing.o hakmem_super_registry.o hakmem_shared_pool.o hakmem_shared_pool_acquire.o hakmem_shared_pool_release.o hakmem_elo.o hakmem_batch.o hakmem_p2.o hakmem_sizeclass_dist.o hakmem_evo.o hakmem_debug.o hakmem_sys.o hakmem_whale.o hakmem_policy.o hakmem_ace.o hakmem_ace_stats.o hakmem_prof.o hakmem_learner.o hakmem_size_hist.o hakmem_learn_log.o hakmem_syscall.o hakmem_ace_metrics.o hakmem_ace_ucb1.o hakmem_ace_controller.o tiny_fastcache.o core/box/superslab_expansion_box.o core/box/integrity_box.o core/box/free_publish_box.o core/box/mailbox_box.o core/box/front_gate_box.o core/box/front_gate_classifier.o core/box/capacity_box.o core/box/carve_push_box.o core/box/prewarm_box.o core/box/ss_hot_prewarm_box.o core/box/front_metrics_box.o core/box/bench_fast_box.o core/box/ss_addr_map_box.o core/box/slab_recycling_box.o core/box/pagefault_telemetry_box.o core/box/tiny_sizeclass_hist_box.o core/box/tiny_env_box.o core/box/tiny_route_box.o core/box/free_front_v3_env_box.o core/box/free_path_stats_box.o core/box/free_dispatch_stats_box.o core/box/alloc_gate_stats_box.o core/box/tiny_c6_ultra_free_box.o core/box/tiny_c5_ultra_free_box.o core/box/tiny_c4_ultra_free_box.o core/box/tiny_page_box.o core/box/tiny_class_policy_box.o core/box/tiny_class_stats_box.o core/box/tiny_policy_learner_box.o core/box/ss_budget_box.o core/box/tiny_mem_stats_box.o core/box/c7_meta_used_counter_box.o core/box/wrapper_env_box.o core/box/madvise_guard_box.o core/box/libm_reloc_guard_box.o core/box/ptr_trace_box.o core/box/link_missing_stubs.o core/box/super_reg_box.o core/box/shared_pool_box.o core/box/remote_side_box.o core/page_arena.o core/front/tiny_unified_cache.o core/tiny_alloc_fast_push.o core/tiny_c7_ultra_segment.o core/tiny_c7_ultra.o core/link_stubs.o core/tiny_failfast.o core/tiny_destructors.o core/smallobject_hotbox_v3.o core/smallobject_hotbox_v4.o core/smallobject_hotbox_v5.o core/smallsegment_v5.o core/smallobject_cold_iface_v5.o core/smallsegment_v6.o core/smallobject_cold_iface_v6.o core/smallobject_core_v6.o core/region_id_v6.o core/smallsegment_v7.o core/smallobject_cold_iface_v7.o core/mid_hotbox_v3.o core/smallobject_policy_v7.o core/smallobject_segment_mid_v3.o core/smallobject_cold_iface_mid_v3.o core/smallobject_stats_mid_v3.o core/smallobject_learner_v2.o core/smallobject_mid_v35.o OBJS = $(OBJS_BASE) # Shared library @@ -250,7 +250,7 @@ endif # Benchmark targets BENCH_HAKMEM = bench_allocators_hakmem BENCH_SYSTEM = bench_allocators_system -BENCH_HAKMEM_OBJS_BASE = hakmem.o hakmem_config.o hakmem_tiny_config.o hakmem_ucb1.o hakmem_bigcache.o hakmem_pool.o hakmem_l25_pool.o hakmem_site_rules.o hakmem_tiny.o core/box/ss_allocation_box.o superslab_stats.o superslab_cache.o superslab_ace.o superslab_slab.o superslab_backend.o core/superslab_head_stub.o hakmem_smallmid.o tiny_sticky.o tiny_remote.o tiny_publish.o tiny_debug_ring.o hakmem_tiny_magazine.o hakmem_tiny_stats.o hakmem_tiny_sfc.o hakmem_tiny_query.o hakmem_tiny_rss.o hakmem_tiny_registry.o hakmem_tiny_remote_target.o hakmem_tiny_bg_spill.o tiny_adaptive_sizing.o hakmem_super_registry.o hakmem_shared_pool.o hakmem_shared_pool_acquire.o hakmem_shared_pool_release.o hakmem_elo.o hakmem_batch.o hakmem_p2.o hakmem_sizeclass_dist.o hakmem_evo.o hakmem_debug.o hakmem_sys.o hakmem_whale.o hakmem_policy.o hakmem_ace.o hakmem_ace_stats.o hakmem_prof.o hakmem_learner.o hakmem_size_hist.o hakmem_learn_log.o hakmem_syscall.o hakmem_ace_metrics.o hakmem_ace_ucb1.o hakmem_ace_controller.o tiny_fastcache.o core/box/superslab_expansion_box.o core/box/integrity_box.o core/box/free_publish_box.o core/box/mailbox_box.o core/box/front_gate_box.o core/box/front_gate_classifier.o core/box/capacity_box.o core/box/carve_push_box.o core/box/prewarm_box.o core/box/ss_hot_prewarm_box.o core/box/front_metrics_box.o core/box/bench_fast_box.o core/box/ss_addr_map_box.o core/box/slab_recycling_box.o core/box/pagefault_telemetry_box.o core/box/tiny_sizeclass_hist_box.o core/box/tiny_env_box.o core/box/tiny_route_box.o core/box/free_front_v3_env_box.o core/box/free_path_stats_box.o core/box/free_dispatch_stats_box.o core/box/alloc_gate_stats_box.o core/box/tiny_c6_ultra_free_box.o core/box/tiny_c5_ultra_free_box.o core/box/tiny_c4_ultra_free_box.o core/box/tiny_page_box.o core/box/tiny_class_policy_box.o core/box/tiny_class_stats_box.o core/box/tiny_policy_learner_box.o core/box/ss_budget_box.o core/box/tiny_mem_stats_box.o core/box/c7_meta_used_counter_box.o core/box/wrapper_env_box.o core/box/madvise_guard_box.o core/box/libm_reloc_guard_box.o core/box/ptr_trace_box.o core/box/link_missing_stubs.o core/box/super_reg_box.o core/box/shared_pool_box.o core/box/remote_side_box.o core/page_arena.o core/front/tiny_unified_cache.o core/tiny_alloc_fast_push.o core/tiny_c7_ultra_segment.o core/tiny_c7_ultra.o core/link_stubs.o core/tiny_failfast.o core/tiny_destructors.o core/smallobject_hotbox_v3.o core/smallobject_hotbox_v4.o core/smallobject_hotbox_v5.o core/smallsegment_v5.o core/smallobject_cold_iface_v5.o core/smallsegment_v6.o core/smallobject_cold_iface_v6.o core/smallobject_core_v6.o core/region_id_v6.o core/smallsegment_v7.o core/smallobject_cold_iface_v7.o core/mid_hotbox_v3.o core/smallobject_policy_v7.o core/smallobject_segment_mid_v3.o core/smallobject_cold_iface_mid_v3.o core/smallobject_stats_mid_v3.o core/smallobject_learner_v2.o bench_allocators_hakmem.o +BENCH_HAKMEM_OBJS_BASE = hakmem.o hakmem_config.o hakmem_tiny_config.o hakmem_ucb1.o hakmem_bigcache.o hakmem_pool.o hakmem_l25_pool.o hakmem_site_rules.o hakmem_tiny.o core/box/ss_allocation_box.o superslab_stats.o superslab_cache.o superslab_ace.o superslab_slab.o superslab_backend.o core/superslab_head_stub.o hakmem_smallmid.o tiny_sticky.o tiny_remote.o tiny_publish.o tiny_debug_ring.o hakmem_tiny_magazine.o hakmem_tiny_stats.o hakmem_tiny_sfc.o hakmem_tiny_query.o hakmem_tiny_rss.o hakmem_tiny_registry.o hakmem_tiny_remote_target.o hakmem_tiny_bg_spill.o tiny_adaptive_sizing.o hakmem_super_registry.o hakmem_shared_pool.o hakmem_shared_pool_acquire.o hakmem_shared_pool_release.o hakmem_elo.o hakmem_batch.o hakmem_p2.o hakmem_sizeclass_dist.o hakmem_evo.o hakmem_debug.o hakmem_sys.o hakmem_whale.o hakmem_policy.o hakmem_ace.o hakmem_ace_stats.o hakmem_prof.o hakmem_learner.o hakmem_size_hist.o hakmem_learn_log.o hakmem_syscall.o hakmem_ace_metrics.o hakmem_ace_ucb1.o hakmem_ace_controller.o tiny_fastcache.o core/box/superslab_expansion_box.o core/box/integrity_box.o core/box/free_publish_box.o core/box/mailbox_box.o core/box/front_gate_box.o core/box/front_gate_classifier.o core/box/capacity_box.o core/box/carve_push_box.o core/box/prewarm_box.o core/box/ss_hot_prewarm_box.o core/box/front_metrics_box.o core/box/bench_fast_box.o core/box/ss_addr_map_box.o core/box/slab_recycling_box.o core/box/pagefault_telemetry_box.o core/box/tiny_sizeclass_hist_box.o core/box/tiny_env_box.o core/box/tiny_route_box.o core/box/free_front_v3_env_box.o core/box/free_path_stats_box.o core/box/free_dispatch_stats_box.o core/box/alloc_gate_stats_box.o core/box/tiny_c6_ultra_free_box.o core/box/tiny_c5_ultra_free_box.o core/box/tiny_c4_ultra_free_box.o core/box/tiny_page_box.o core/box/tiny_class_policy_box.o core/box/tiny_class_stats_box.o core/box/tiny_policy_learner_box.o core/box/ss_budget_box.o core/box/tiny_mem_stats_box.o core/box/c7_meta_used_counter_box.o core/box/wrapper_env_box.o core/box/madvise_guard_box.o core/box/libm_reloc_guard_box.o core/box/ptr_trace_box.o core/box/link_missing_stubs.o core/box/super_reg_box.o core/box/shared_pool_box.o core/box/remote_side_box.o core/page_arena.o core/front/tiny_unified_cache.o core/tiny_alloc_fast_push.o core/tiny_c7_ultra_segment.o core/tiny_c7_ultra.o core/link_stubs.o core/tiny_failfast.o core/tiny_destructors.o core/smallobject_hotbox_v3.o core/smallobject_hotbox_v4.o core/smallobject_hotbox_v5.o core/smallsegment_v5.o core/smallobject_cold_iface_v5.o core/smallsegment_v6.o core/smallobject_cold_iface_v6.o core/smallobject_core_v6.o core/region_id_v6.o core/smallsegment_v7.o core/smallobject_cold_iface_v7.o core/mid_hotbox_v3.o core/smallobject_policy_v7.o core/smallobject_segment_mid_v3.o core/smallobject_cold_iface_mid_v3.o core/smallobject_stats_mid_v3.o core/smallobject_learner_v2.o core/smallobject_mid_v35.o bench_allocators_hakmem.o BENCH_HAKMEM_OBJS = $(BENCH_HAKMEM_OBJS_BASE) ifeq ($(POOL_TLS_PHASE1),1) BENCH_HAKMEM_OBJS += pool_tls.o pool_refill.o pool_tls_arena.o pool_tls_registry.o pool_tls_remote.o @@ -427,7 +427,7 @@ test-box-refactor: box-refactor ./larson_hakmem 10 8 128 1024 1 12345 4 # Phase 4: Tiny Pool benchmarks (properly linked with hakmem) -TINY_BENCH_OBJS_BASE = hakmem.o hakmem_config.o hakmem_tiny_config.o hakmem_ucb1.o hakmem_bigcache.o hakmem_pool.o hakmem_l25_pool.o hakmem_site_rules.o hakmem_tiny.o core/box/ss_allocation_box.o superslab_stats.o superslab_cache.o superslab_ace.o superslab_slab.o superslab_backend.o core/superslab_head_stub.o hakmem_smallmid.o core/box/superslab_expansion_box.o core/box/integrity_box.o core/box/mailbox_box.o core/box/front_gate_box.o core/box/front_gate_classifier.o core/box/free_publish_box.o core/box/capacity_box.o core/box/carve_push_box.o core/box/prewarm_box.o core/box/ss_hot_prewarm_box.o core/box/front_metrics_box.o core/box/bench_fast_box.o core/box/ss_addr_map_box.o core/box/slab_recycling_box.o core/box/pagefault_telemetry_box.o core/box/tiny_sizeclass_hist_box.o core/box/tiny_env_box.o core/box/tiny_route_box.o core/box/free_front_v3_env_box.o core/box/free_path_stats_box.o core/box/free_dispatch_stats_box.o core/box/alloc_gate_stats_box.o core/box/tiny_c6_ultra_free_box.o core/box/tiny_c5_ultra_free_box.o core/box/tiny_c4_ultra_free_box.o core/box/tiny_page_box.o core/box/tiny_class_policy_box.o core/box/tiny_class_stats_box.o core/box/tiny_policy_learner_box.o core/box/ss_budget_box.o core/box/tiny_mem_stats_box.o core/box/c7_meta_used_counter_box.o core/box/wrapper_env_box.o core/box/madvise_guard_box.o core/box/libm_reloc_guard_box.o core/box/ptr_trace_box.o core/box/link_missing_stubs.o core/box/super_reg_box.o core/box/shared_pool_box.o core/box/remote_side_box.o core/page_arena.o core/front/tiny_unified_cache.o tiny_sticky.o tiny_remote.o tiny_publish.o tiny_debug_ring.o hakmem_tiny_magazine.o hakmem_tiny_stats.o hakmem_tiny_sfc.o hakmem_tiny_query.o hakmem_tiny_rss.o hakmem_tiny_registry.o hakmem_tiny_remote_target.o hakmem_tiny_bg_spill.o tiny_adaptive_sizing.o hakmem_super_registry.o hakmem_shared_pool.o hakmem_shared_pool_acquire.o hakmem_shared_pool_release.o hakmem_elo.o hakmem_batch.o hakmem_p2.o hakmem_sizeclass_dist.o hakmem_evo.o hakmem_debug.o hakmem_sys.o hakmem_whale.o hakmem_policy.o hakmem_ace.o hakmem_ace_stats.o hakmem_prof.o hakmem_learner.o hakmem_size_hist.o hakmem_learn_log.o hakmem_syscall.o hakmem_ace_metrics.o hakmem_ace_ucb1.o hakmem_ace_controller.o tiny_fastcache.o core/tiny_alloc_fast_push.o core/tiny_c7_ultra_segment.o core/tiny_c7_ultra.o core/link_stubs.o core/tiny_failfast.o core/tiny_destructors.o core/smallobject_hotbox_v3.o core/smallobject_hotbox_v4.o core/smallobject_hotbox_v5.o core/smallsegment_v5.o core/smallobject_cold_iface_v5.o core/smallsegment_v6.o core/smallobject_cold_iface_v6.o core/smallobject_core_v6.o core/region_id_v6.o core/smallsegment_v7.o core/smallobject_cold_iface_v7.o core/mid_hotbox_v3.o core/smallobject_policy_v7.o core/smallobject_segment_mid_v3.o core/smallobject_cold_iface_mid_v3.o core/smallobject_stats_mid_v3.o core/smallobject_learner_v2.o +TINY_BENCH_OBJS_BASE = hakmem.o hakmem_config.o hakmem_tiny_config.o hakmem_ucb1.o hakmem_bigcache.o hakmem_pool.o hakmem_l25_pool.o hakmem_site_rules.o hakmem_tiny.o core/box/ss_allocation_box.o superslab_stats.o superslab_cache.o superslab_ace.o superslab_slab.o superslab_backend.o core/superslab_head_stub.o hakmem_smallmid.o core/box/superslab_expansion_box.o core/box/integrity_box.o core/box/mailbox_box.o core/box/front_gate_box.o core/box/front_gate_classifier.o core/box/free_publish_box.o core/box/capacity_box.o core/box/carve_push_box.o core/box/prewarm_box.o core/box/ss_hot_prewarm_box.o core/box/front_metrics_box.o core/box/bench_fast_box.o core/box/ss_addr_map_box.o core/box/slab_recycling_box.o core/box/pagefault_telemetry_box.o core/box/tiny_sizeclass_hist_box.o core/box/tiny_env_box.o core/box/tiny_route_box.o core/box/free_front_v3_env_box.o core/box/free_path_stats_box.o core/box/free_dispatch_stats_box.o core/box/alloc_gate_stats_box.o core/box/tiny_c6_ultra_free_box.o core/box/tiny_c5_ultra_free_box.o core/box/tiny_c4_ultra_free_box.o core/box/tiny_page_box.o core/box/tiny_class_policy_box.o core/box/tiny_class_stats_box.o core/box/tiny_policy_learner_box.o core/box/ss_budget_box.o core/box/tiny_mem_stats_box.o core/box/c7_meta_used_counter_box.o core/box/wrapper_env_box.o core/box/madvise_guard_box.o core/box/libm_reloc_guard_box.o core/box/ptr_trace_box.o core/box/link_missing_stubs.o core/box/super_reg_box.o core/box/shared_pool_box.o core/box/remote_side_box.o core/page_arena.o core/front/tiny_unified_cache.o tiny_sticky.o tiny_remote.o tiny_publish.o tiny_debug_ring.o hakmem_tiny_magazine.o hakmem_tiny_stats.o hakmem_tiny_sfc.o hakmem_tiny_query.o hakmem_tiny_rss.o hakmem_tiny_registry.o hakmem_tiny_remote_target.o hakmem_tiny_bg_spill.o tiny_adaptive_sizing.o hakmem_super_registry.o hakmem_shared_pool.o hakmem_shared_pool_acquire.o hakmem_shared_pool_release.o hakmem_elo.o hakmem_batch.o hakmem_p2.o hakmem_sizeclass_dist.o hakmem_evo.o hakmem_debug.o hakmem_sys.o hakmem_whale.o hakmem_policy.o hakmem_ace.o hakmem_ace_stats.o hakmem_prof.o hakmem_learner.o hakmem_size_hist.o hakmem_learn_log.o hakmem_syscall.o hakmem_ace_metrics.o hakmem_ace_ucb1.o hakmem_ace_controller.o tiny_fastcache.o core/tiny_alloc_fast_push.o core/tiny_c7_ultra_segment.o core/tiny_c7_ultra.o core/link_stubs.o core/tiny_failfast.o core/tiny_destructors.o core/smallobject_hotbox_v3.o core/smallobject_hotbox_v4.o core/smallobject_hotbox_v5.o core/smallsegment_v5.o core/smallobject_cold_iface_v5.o core/smallsegment_v6.o core/smallobject_cold_iface_v6.o core/smallobject_core_v6.o core/region_id_v6.o core/smallsegment_v7.o core/smallobject_cold_iface_v7.o core/mid_hotbox_v3.o core/smallobject_policy_v7.o core/smallobject_segment_mid_v3.o core/smallobject_cold_iface_mid_v3.o core/smallobject_stats_mid_v3.o core/smallobject_learner_v2.o core/smallobject_mid_v35.o TINY_BENCH_OBJS = $(TINY_BENCH_OBJS_BASE) ifeq ($(POOL_TLS_PHASE1),1) TINY_BENCH_OBJS += pool_tls.o pool_refill.o core/pool_tls_arena.o pool_tls_registry.o pool_tls_remote.o diff --git a/core/box/smallobject_mid_v35_box.h b/core/box/smallobject_mid_v35_box.h new file mode 100644 index 00000000..031ad243 --- /dev/null +++ b/core/box/smallobject_mid_v35_box.h @@ -0,0 +1,47 @@ +// smallobject_mid_v35_box.h +// Phase v11a-3: MID v3.5 Public API (L1 HotBox) +// +// Purpose: +// - Fast-path alloc/free for C5/C6/C7 (257-1024B range) +// - Uses Segment v2 + ColdIface v2 + Stats v2 + Learner v2 +// - TLS-cached page allocation with refill/retire via ColdIface + +#ifndef SMALLOBJECT_MID_V35_BOX_H +#define SMALLOBJECT_MID_V35_BOX_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// ============================================================================ +// MID v3.5 Public API (called from malloc_tiny_fast.h) +// ============================================================================ + +/** + * Allocate from MID v3.5 path + * @param class_idx: Size class (C5/C6/C7 only) + * @param size: Requested size (for validation/debugging) + * @return USER pointer or NULL on failure + */ +void* small_mid_v35_alloc(uint32_t class_idx, size_t size); + +/** + * Free to MID v3.5 path + * @param ptr: USER pointer to free + * @param class_idx: Size class (C5/C6/C7 only) + */ +void small_mid_v35_free(void *ptr, uint32_t class_idx); + +/** + * Initialize MID v3.5 (called from hakmem init) + */ +void small_mid_v35_init(void); + +#ifdef __cplusplus +} +#endif + +#endif // SMALLOBJECT_MID_V35_BOX_H diff --git a/core/box/smallobject_policy_v7_box.h b/core/box/smallobject_policy_v7_box.h index f9590121..4f6483db 100644 --- a/core/box/smallobject_policy_v7_box.h +++ b/core/box/smallobject_policy_v7_box.h @@ -21,6 +21,7 @@ typedef enum { SMALL_ROUTE_ULTRA, // L0: C4-C7 ULTRA (FROZEN) SMALL_ROUTE_V7, // L1: SmallObject v7 (research box) SMALL_ROUTE_MID_V3, // L1': MID v3 (257-768B mid/small) + SMALL_ROUTE_MID_V35, // L1': MID v3.5 (v11a-3: Segment/ColdIface/Stats/Learner v2) SMALL_ROUTE_LEGACY, // L1': TinyHeap v1 / Pool v1 (fallback) } SmallRouteKind; diff --git a/core/front/malloc_tiny_fast.h b/core/front/malloc_tiny_fast.h index 72a8e71a..079e099d 100644 --- a/core/front/malloc_tiny_fast.h +++ b/core/front/malloc_tiny_fast.h @@ -47,6 +47,7 @@ #include "../box/smallobject_v6_env_box.h" // SmallObject v6 ENV control (Phase V6-HDR-2) #include "../box/smallobject_hotbox_v7_box.h" // SmallObject HotBox v7 stub (Phase v7-1) #include "../box/smallobject_policy_v7_box.h" // Phase v7-4: Policy Box +#include "../box/smallobject_mid_v35_box.h" // Phase v11a-3: MID v3.5 HotBox #include "../box/tiny_c7_ultra_box.h" // C7 ULTRA stub (UF-1, delegates to v3) #include "../box/tiny_c6_ultra_free_box.h" // Phase 4-2: C6 ULTRA-free (free-only, C6-only) #include "../box/tiny_c5_ultra_free_box.h" // Phase 5-1/5-2: C5 ULTRA-free + alloc integration @@ -224,8 +225,18 @@ static inline void* malloc_tiny_fast(size_t size) { } } - // Phase v7-4: Check Policy Box for v7 routing (before switch) + // Phase v7-4: Check Policy Box for v7/MID_V35 routing (before switch) const SmallPolicyV7* policy = small_policy_v7_snapshot(); + + // Phase v11a-3: MID v3.5 routing + if (policy->route_kind[class_idx] == SMALL_ROUTE_MID_V35) { + void* v35p = small_mid_v35_alloc(class_idx, size); + if (TINY_HOT_LIKELY(v35p != NULL)) { + return v35p; + } + // v35 returned NULL -> fallback to legacy + } + if (policy->route_kind[class_idx] == SMALL_ROUTE_V7) { void* v7p = small_heap_alloc_fast_v7_stub(size, (uint8_t)class_idx); if (TINY_HOT_LIKELY(v7p != NULL)) { @@ -378,6 +389,17 @@ static inline int free_tiny_fast(void* ptr) { return 1; } + // Phase v11a-3: Try MID v3.5 free for C5/C6/C7 + // For v11a-3: simple ownership check (assumes current route) + // For v11b: will add proper segment-based ownership check + const SmallPolicyV7* policy_free = small_policy_v7_snapshot(); + if ((class_idx >= 5 && class_idx <= 7) && + policy_free->route_kind[class_idx] == SMALL_ROUTE_MID_V35) { + small_mid_v35_free(ptr, class_idx); + FREE_PATH_STAT_INC(smallheap_v7_fast); // Reuse counter for now + return 1; + } + // Phase v7-5b/v7-7: Always try V7 free for supported classes (C5/C6) // V7 returns false if ptr is not in V7 segment. // This is necessary because Learner may switch routes dynamically, diff --git a/core/smallobject_mid_v35.c b/core/smallobject_mid_v35.c new file mode 100644 index 00000000..66dfa9d1 --- /dev/null +++ b/core/smallobject_mid_v35.c @@ -0,0 +1,168 @@ +// smallobject_mid_v35.c +// Phase v11a-3: MID v3.5 HotBox implementation +// +// Design: +// - TLS-cached page for fast allocation +// - Refill via ColdIface when page exhausted +// - Retire via ColdIface when page is full +// - Stats/Learner integration for observability + +#include +#include +#include +#include "box/smallobject_mid_v35_box.h" +#include "box/smallobject_segment_mid_v3_box.h" +#include "box/smallobject_cold_iface_mid_v3_box.h" +#include "tiny_region_id.h" // For tiny_region_id_write_header + +// Reuse SmallPageMeta from segment implementation (matches cold_iface) +typedef struct SmallPageMeta { + void *ptr; + uint32_t capacity; + uint8_t class_idx; + uint32_t alloc_count; + uint32_t free_count; + void *segment; + struct SmallPageMeta *next; +} SmallPageMeta; + +// ============================================================================ +// TLS Context (per-thread fast path state) +// ============================================================================ + +typedef struct { + void *page[8]; // Current page per class + uint32_t offset[8]; // Allocation offset (slot index) + uint32_t capacity[8]; // Slots per page per class + SmallPageMeta *meta[8]; // Page metadata for retire check +} SmallMidV35TlsCtx; + +static __thread SmallMidV35TlsCtx tls_mid_v35_ctx = {0}; + +// ============================================================================ +// Slot Configuration (C5/C6/C7) +// ============================================================================ + +// Slot sizes for C5, C6, C7 +static const size_t g_slot_sizes[8] = { + 0, // C0: not used + 0, // C1: not used + 0, // C2: not used + 0, // C3: not used + 0, // C4: not used (ULTRA handles this) + 384, // C5: 257-384 bytes → 384 byte slots + 512, // C6: 385-512 bytes → 512 byte slots + 1024, // C7: 513-1024 bytes → 1024 byte slots (ULTRA handles this) +}; + +// Slots per 64KB page +static const uint32_t g_slots_per_page[8] = { + 0, 0, 0, 0, 0, + 170, // C5: 65536 / 384 = 170 + 128, // C6: 65536 / 512 = 128 + 64, // C7: 65536 / 1024 = 64 +}; + +// ============================================================================ +// Init +// ============================================================================ + +void small_mid_v35_init(void) { + // Initialize any global state if needed + // For v11a-3: nothing to do (TLS is zero-initialized) +} + +// ============================================================================ +// Alloc +// ============================================================================ + +void* small_mid_v35_alloc(uint32_t class_idx, size_t size) { + if (class_idx < 5 || class_idx > 7) return NULL; // Only C5-C7 + + SmallMidV35TlsCtx *ctx = &tls_mid_v35_ctx; + + // Fast path: allocate from TLS cached page + if (ctx->page[class_idx] && ctx->offset[class_idx] < ctx->capacity[class_idx]) { + size_t slot_size = g_slot_sizes[class_idx]; + void *base = (char*)ctx->page[class_idx] + ctx->offset[class_idx] * slot_size; + ctx->offset[class_idx]++; + + // Update page metadata + if (ctx->meta[class_idx]) { + ctx->meta[class_idx]->alloc_count++; + } + + // Write header (1-byte Tiny header with class_idx) + // Note: Assumes HAKMEM_TINY_HEADER_CLASSIDX is enabled + tiny_region_id_write_header(base, class_idx); + + // Return USER pointer (BASE + 1 byte header) + return (char*)base + 1; + } + + // Slow path: need new page via ColdIface + SmallPageMeta *page = small_cold_mid_v3_refill_page(class_idx); + if (!page) { + // Fallback to legacy or return NULL + return NULL; + } + + // Update TLS cache + ctx->page[class_idx] = page->ptr; + ctx->offset[class_idx] = 1; // First slot already allocated + ctx->capacity[class_idx] = g_slots_per_page[class_idx]; + ctx->meta[class_idx] = page; + + // Record first allocation in page metadata + page->alloc_count = 1; + + // Write header for first slot + tiny_region_id_write_header(page->ptr, class_idx); + + // Return first slot (USER pointer) + return (char*)page->ptr + 1; +} + +// ============================================================================ +// Free (Simplified: just count, no freelist yet) +// ============================================================================ + +void small_mid_v35_free(void *ptr, uint32_t class_idx) { + if (!ptr || class_idx < 5 || class_idx > 7) return; + + // For v11a-3: simplified free (just increment free_count) + // In future phases: implement freelist for reuse + + // Calculate BASE from USER pointer + void *base = (char*)ptr - 1; + + // Find page metadata via simple calculation + // Note: Assumes 64KB pages aligned to 64KB boundary + size_t page_size = 64 * 1024; // 64KB + void *page_base = (void*)((uintptr_t)base & ~(page_size - 1)); + + // Check if this is the current TLS page + SmallMidV35TlsCtx *ctx = &tls_mid_v35_ctx; + SmallPageMeta *meta = ctx->meta[class_idx]; + + if (meta && meta->ptr == page_base) { + // Free to current TLS page + meta->free_count++; + + // Check if page is fully empty + if (meta->free_count >= meta->capacity) { + // Retire page via ColdIface + small_cold_mid_v3_retire_page(meta); + + // Clear TLS cache for this class + ctx->page[class_idx] = NULL; + ctx->offset[class_idx] = 0; + ctx->meta[class_idx] = NULL; + } + } else { + // Different page: need RegionIdBox lookup + // For v11a-3: simple fallback - just count the free + // Real implementation needs proper page lookup + // TODO: Implement cross-page free via RegionIdBox in v11b + } +} diff --git a/core/smallobject_policy_v7.c b/core/smallobject_policy_v7.c index 4617a9a2..397967af 100644 --- a/core/smallobject_policy_v7.c +++ b/core/smallobject_policy_v7.c @@ -75,6 +75,23 @@ static inline uint32_t env_class_mask(const char* name, uint32_t default_mask) { return default_mask; } +// ============================================================================ +// MID v3.5 ENV Helpers (Phase v11a-3) +// ============================================================================ + +static inline bool mid_v35_enabled(void) { + const char* e = getenv("HAKMEM_MID_V35_ENABLED"); + return (e && *e && *e != '0'); +} + +static inline uint32_t mid_v35_class_mask(void) { + const char* e = getenv("HAKMEM_MID_V35_CLASSES"); + if (e && *e) { + return (uint32_t)strtoul(e, NULL, 0); + } + return 0x60; // Default: C5(0x20) + C6(0x40) +} + // ============================================================================ // Policy Initialization from ENV // ============================================================================ @@ -87,7 +104,7 @@ void small_policy_v7_init_from_env(SmallPolicyV7* policy) { policy->route_kind[i] = SMALL_ROUTE_LEGACY; } - // Priority 3: MID_v3 (257-768B, C5-C6 range) + // Priority 4: MID_v3 (257-768B, C5-C6 range) // ENV: HAKMEM_MID_V3_ENABLED, HAKMEM_MID_V3_CLASSES if (env_enabled("HAKMEM_MID_V3_ENABLED")) { uint32_t mid_mask = env_class_mask("HAKMEM_MID_V3_CLASSES", 0x60); // C5-C6 default @@ -98,6 +115,20 @@ void small_policy_v7_init_from_env(SmallPolicyV7* policy) { } } + // Priority 3: MID_v3.5 (Phase v11a-3: higher priority than MID_v3) + // ENV: HAKMEM_MID_V35_ENABLED, HAKMEM_MID_V35_CLASSES + if (mid_v35_enabled()) { + uint32_t v35_mask = mid_v35_class_mask(); + for (int i = 0; i < 8; i++) { + if (v35_mask & (1u << i)) { + // Only override if not ULTRA + if (policy->route_kind[i] != SMALL_ROUTE_ULTRA) { + policy->route_kind[i] = SMALL_ROUTE_MID_V35; + } + } + } + } + // Priority 2: SmallObject v7 (research box, C6-only for now) // ENV: HAKMEM_SMALL_HEAP_V7_ENABLED, HAKMEM_SMALL_HEAP_V7_CLASSES if (env_enabled("HAKMEM_SMALL_HEAP_V7_ENABLED")) { @@ -145,6 +176,7 @@ const char* small_route_kind_name(SmallRouteKind kind) { case SMALL_ROUTE_ULTRA: return "ULTRA"; case SMALL_ROUTE_V7: return "V7"; case SMALL_ROUTE_MID_V3: return "MID_V3"; + case SMALL_ROUTE_MID_V35: return "MID_V35"; case SMALL_ROUTE_LEGACY: return "LEGACY"; default: return "UNKNOWN"; } diff --git a/docs/analysis/PHASE_V11A3_IMPLEMENTATION_SUMMARY.md b/docs/analysis/PHASE_V11A3_IMPLEMENTATION_SUMMARY.md new file mode 100644 index 00000000..166511b3 --- /dev/null +++ b/docs/analysis/PHASE_V11A3_IMPLEMENTATION_SUMMARY.md @@ -0,0 +1,226 @@ +# Phase v11a-3: MID v3.5 Implementation Summary + +**Date:** 2025-12-12 +**Status:** Build Complete - Ready for A/B Benchmarking +**Author:** Claude Opus 4.5 + +## Overview + +Phase v11a-3 successfully integrated MID v3.5 into the active code path, making it available for routing C5/C6/C7 allocations. This phase activates the Segment/ColdIface/Stats/Learner v2 infrastructure implemented in Phase v11a-2. + +## Implementation Tasks Completed + +### Task 1: Policy Box Updates (L3) + +**Files Modified:** +- `/mnt/workdisk/public_share/hakmem/core/box/smallobject_policy_v7_box.h` +- `/mnt/workdisk/public_share/hakmem/core/smallobject_policy_v7.c` + +**Changes:** +1. Added `SMALL_ROUTE_MID_V35` to `SmallRouteKind` enum +2. Implemented ENV gate functions: + - `mid_v35_enabled()` - checks `HAKMEM_MID_V35_ENABLED` + - `mid_v35_class_mask()` - reads `HAKMEM_MID_V35_CLASSES` (default: 0x60 for C5+C6) +3. Updated policy init with priority: ULTRA > MID_V35 > V7 > MID_V3 > LEGACY +4. Added MID_V35 case to `small_route_kind_name()` + +### Task 2: MID v3.5 HotBox Implementation (L1) + +**Files Created:** +- `/mnt/workdisk/public_share/hakmem/core/box/smallobject_mid_v35_box.h` - Public API +- `/mnt/workdisk/public_share/hakmem/core/smallobject_mid_v35.c` - Implementation + +**Implementation:** +- TLS-cached page allocation (per-class fast path) +- Slot sizes: C5=384B, C6=512B, C7=1024B +- Page size: 64KB (170/128/64 slots for C5/C6/C7) +- Alloc: Fast path (TLS cache hit) + Slow path (refill via ColdIface) +- Free: Simplified counting (no freelist yet - deferred to v11b) +- Header writing: Integrates with tiny_region_id_write_header + +**Key Design Decisions:** +- Reused `SmallPageMeta` typedef (matches segment/cold_iface structure) +- Simplified free path (cross-page free deferred to v11b RegionIdBox integration) +- Header integration for compatibility with existing Tiny infrastructure + +### Task 3: Front Gate Integration (L0/L1 Boundary) + +**Files Modified:** +- `/mnt/workdisk/public_share/hakmem/core/front/malloc_tiny_fast.h` + +**Changes:** +1. Added MID v3.5 box header include +2. Alloc path: Check policy for MID_V35, call `small_mid_v35_alloc()` before V7 +3. Free path: Check policy for MID_V35, call `small_mid_v35_free()` after ULTRA checks + +**Priority Order (Alloc/Free):** +1. ULTRA (C4-C7) +2. MID v3.5 (Policy-driven) +3. V7 (Policy-driven) +4. Legacy routes + +### Task 4: Build System Updates + +**Files Modified:** +- `/mnt/workdisk/public_share/hakmem/Makefile` + +**Changes:** +- Added `core/smallobject_mid_v35.o` to `OBJS_BASE` +- Added `core/smallobject_mid_v35.o` to `BENCH_HAKMEM_OBJS_BASE` +- Added `core/smallobject_mid_v35.o` to `TINY_BENCH_OBJS_BASE` + +**Build Results:** +- Clean build successful +- Benchmarks compiled: `bench_random_mixed_hakmem`, `bench_mid_large_mt_hakmem` +- Minor warnings (unused parameter `size`) - non-critical + +## ENV Configuration + +### MID v3.5 Activation + +```bash +# Enable MID v3.5 +export HAKMEM_MID_V35_ENABLED=1 + +# Configure classes (default: 0x60 = C5+C6) +export HAKMEM_MID_V35_CLASSES=0x60 # C5 + C6 +# export HAKMEM_MID_V35_CLASSES=0x20 # C5 only +# export HAKMEM_MID_V35_CLASSES=0x40 # C6 only +``` + +### Policy Debug Output + +Policy initialization prints route assignments on first call: +``` +[POLICY_V7_INIT] Route assignments: + C0: LEGACY + C1: LEGACY + C2: LEGACY + C3: LEGACY + C4: ULTRA + C5: MID_V35 + C6: MID_V35 + C7: ULTRA +``` + +## Next Steps (Task 5: A/B Benchmarks) + +### Benchmark 1: C6-Heavy (MID Specialization Check) + +```bash +# Baseline: MID v3.5 OFF +HAKMEM_PROFILE=C6_HEAVY_LEGACY_POOLV1 \ +HAKMEM_MID_V35_ENABLED=0 \ +./bench_mid_large_mt_hakmem 1 1000000 400 1 + +# Test: MID v3.5 ON (C6 only) +HAKMEM_PROFILE=C6_HEAVY_LEGACY_POOLV1 \ +HAKMEM_MID_V35_ENABLED=1 \ +HAKMEM_MID_V35_CLASSES=0x40 \ +./bench_mid_large_mt_hakmem 1 1000000 400 1 +``` + +**Expected:** Performance within ±5% of MID v3 + +### Benchmark 2: C5+C6-Only (257-768B Range) + +```bash +# Baseline: MID v3.5 OFF +HAKMEM_BENCH_MIN_SIZE=257 \ +HAKMEM_BENCH_MAX_SIZE=768 \ +HAKMEM_MID_V35_ENABLED=0 \ +./bench_random_mixed_hakmem 1000000 400 1 + +# Test: MID v3.5 ON (C5+C6) +HAKMEM_BENCH_MIN_SIZE=257 \ +HAKMEM_BENCH_MAX_SIZE=768 \ +HAKMEM_MID_V35_ENABLED=1 \ +HAKMEM_MID_V35_CLASSES=0x60 \ +./bench_random_mixed_hakmem 1000000 400 1 +``` + +**Expected:** +2-4% improvement (matching v7 gains) + +### Benchmark 3: Mixed 16-1024B (Reference) + +```bash +HAKMEM_PROFILE=MIXED_TINYV3_C7_SAFE \ +HAKMEM_MID_V35_ENABLED=1 \ +HAKMEM_MID_V35_CLASSES=0x60 \ +./bench_random_mixed_hakmem 1000000 400 1 +``` + +**Expected:** Baseline ±3% (no regression) + +## Known Limitations (Deferred to v11b) + +1. **Cross-Page Free:** Current implementation only handles frees to the current TLS page + - Need RegionIdBox lookup for cross-page free + - Planned for v11b with proper segment ownership check + +2. **Freelist Reuse:** No freelist implementation yet + - Slots are marked free via counter only + - Full freelist support planned for v11b + +3. **Learner Route Switching:** Learner v2 is in observation mode only + - Dynamic route switching deferred to v11b + - Current implementation: static routing based on ENV + +## Code Quality + +- **Modularity:** Clean L1/L2/L3 separation maintained +- **Box Boundaries:** Proper isolation between HotBox/ColdIface/Stats/Learner +- **Header Compatibility:** Integrates with existing Tiny region_id infrastructure +- **Build Hygiene:** All targets compile cleanly (only unused parameter warnings) + +## Files Summary + +### New Files (2) +1. `core/box/smallobject_mid_v35_box.h` - Public API (48 lines) +2. `core/smallobject_mid_v35.c` - Implementation (165 lines) + +### Modified Files (4) +1. `core/box/smallobject_policy_v7_box.h` - Enum update +2. `core/smallobject_policy_v7.c` - ENV helpers + priority logic +3. `core/front/malloc_tiny_fast.h` - Route integration +4. `Makefile` - Object file lists (3 locations) + +### Total Code Addition +- **New:** ~213 lines +- **Modified:** ~60 lines +- **Total Impact:** ~273 lines + +## Architecture Notes + +### Layer Interaction (L0→L1→L2→L3) + +``` +L0 (Front) malloc_tiny_fast.h + ↓ (Policy check: MID_V35?) +L1 (HotBox) smallobject_mid_v35.c + ↓ (Refill needed?) +L2 (Cold) smallobject_cold_iface_mid_v3.c + ↓ (Get page from segment) +L2 (Segment) smallobject_segment_mid_v3.c + ↓ (Stats recording) +L2 (Stats) smallobject_stats_mid_v3.c + ↓ (Learner evaluation - observation only) +L2 (Learner) smallobject_learner_v2.c + ↓ (Policy update - dormant) +L3 (Policy) smallobject_policy_v7.c +``` + +### Memory Layout + +- **Segment:** 2 MiB contiguous region +- **Pages:** 64KB per page +- **Slots:** 384B (C5), 512B (C6), 1024B (C7) +- **TLS Cache:** One current page per class per thread + +## Conclusion + +Phase v11a-3 successfully activated MID v3.5 infrastructure. The implementation is ready for A/B benchmarking to validate performance against the original MID v3 and establish a baseline for future optimizations. + +**Status:** ✅ Build Complete +**Next:** Task 5 (A/B Benchmarks) - Performance validation +**Future:** Task 6 (Documentation) - Results recording