Files
hakmem/docs/analysis/FREE_FRONT_V3_DESIGN.md
Moe Charm (CI) 7b7de53167 Phase FREE-FRONT-V3-1: Free route snapshot infrastructure + build fix
Summary:
========
Implemented Phase FREE-FRONT-V3 infrastructure to optimize free hotpath by:
1. Creating snapshot-based route decision table (consolidating route logic)
2. Removing redundant ENV checks from hot path
3. Preparing for future integration into hak_free_at()

Key Changes:
============

1. NEW FILES:
   - core/box/free_front_v3_env_box.h: Route snapshot definition & API
   - core/box/free_front_v3_env_box.c: Snapshot initialization & caching

2. Infrastructure Details:
   - FreeRouteSnapshotV3: Maps class_idx → free_route_kind for all 8 classes
   - Routes defined: LEGACY, TINY_V3, CORE_V6_C6, POOL_V1
   - ENV-gated initialization (HAKMEM_TINY_FREE_FRONT_V3_ENABLED, default OFF)
   - Per-thread TLS caching to avoid repeated ENV reads

3. Design Goals:
   - Consolidate tiny_route_for_class() results into snapshot table
   - Remove C7 ULTRA / v4 / v5 / v6 ENV checks from hot path
   - Limit lookup (ss_fast_lookup/slab_index_for) to paths that truly need it
   - Clear ownership boundary: front v3 handles routing, downstream handles free

4. Phase Plan:
   - v3-1  COMPLETE: Infrastructure (snapshot table, ENV initialization, TLS cache)
   - v3-2 (INFRASTRUCTURE ONLY): Placeholder integration in hak_free_api.inc.h
   - v3-3 (FUTURE): Full integration + benchmark A/B to measure hotpath improvement

5. BUILD FIX:
   - Added missing core/box/c7_meta_used_counter_box.o to OBJS_BASE in Makefile
   - This symbol was referenced but not linked, causing undefined reference errors
   - Benchmark targets now build cleanly without LTO

Status:
=======
- Build:  PASS (bench_allocators_hakmem builds without errors)
- Integration: Currently DISABLED (default OFF, ready for v3-2 phase)
- No performance impact: Infrastructure-only, hotpath unchanged

Future Work:
============
- Phase v3-2: Integrate snapshot routing into hak_free_at() main path
- Phase v3-3: Measure free hotpath performance improvement (target: 1-2% less branch mispredict)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-11 19:17:30 +09:00

5.0 KiB
Raw Blame History

Free Front v3 設計メモ

目的

Mixed 161024B における free hotpathfree ≈ 2336%, tiny_alloc_gate_fast ≈ 22%)を、
「header 読み + route 決定 + 1 回の dispatch」に近づけることを目標に、free front v3 の構造を整理する。

v6/vULTRA でやりたかった「lookup を避ける」「TLS 所有で早期 free」を、free 前段の設計に統合する。


現状 free front のフローとボトルネック

現状フロー(簡略図)

free
  → hak_free_at
    → fg_classify_domain
      → fg_tiny_gate
        → tiny_free_gate_try_fast
          → hak_tiny_free_fast_v2
            → ss_fast_lookup(ptr)
            → slab_index_for(ptr)
            → tiny_get_class_from_ss()
            → TLS push / remote / pool free...

free_tiny_fast 相当の処理は概ね次のステップから成る:

  1. header 読み取り + magic checkOK
  2. class_idx 抽出OK
  3. stats incrementOK
  4. C7 ULTRA checkENV gate
  5. C7 v3 checkENV gate
  6. tiny_route_for_class() 呼び出し(毎 free
  7. v4/v5/v6 など複数の ENV check
  8. tiny_route_is_heap_kind() で heap/legacy 判定
  9. tiny_front_v3_snapshot_get() で front snapshot/TLS 判定
  10. ss_fast_lookup(base) + slab_index_for() で Superslab/スラブ index 解決
  11. Larson cross-thread checkowner/TLS 判定)
  12. 最後に route に応じた switch/case で実 free 実行

問題点

  • tiny_route_for_class() を free 毎に呼んでいるclass→route は snapshot で cache 可能)。
  • tiny_front_v3_snapshot_get() を毎 free で呼んでいる。
  • ss_fast_lookup + slab_index_for が free 前段にぶら下がっており、
    「lookup を避ける」という v6/vULTRA の目標と構造的に衝突している。
  • C7 ULTRA / v4 / v5 / v6 など複数の ENV 判定が HotPath に並んでいて、branch mispredict の要因になっている。

free front v3 の目標

free front v3 では、次の 3 点を達成する:

  1. route 決定を snapshot に閉じ込める

    • tiny_route_for_class() の結果や各種 ENV を、起動時/スナップショット更新時に route_kind[class_idx] テーブルに焼き込む。
    • free 時には「header→class_idx→route_kind」をテーブル 1 回参照で決める。
  2. ENV check を HotPath から外す

    • C7 ULTRA / v4 / v5 / v6 などの ON/OFF 判定は snapshot 初期化時に反映し、
      free のホットパスでは ENV を直接読まない。
  3. lookupss_fast_lookup/slab_index_forを “本当に必要な場面だけ” に限定

    • C6/C5/C4 など Core v6/Tiny/v3 が TLS 所有を持っているクラスでは、small_tls_owns_ptr_v6 や C7 ULTRA の mask 判定で Superslab lookup を飛ばす。
    • Superslab/pool v1 経路でのみ lookup を使い、free front v3 の基本ルートからは排除する。

理想的な free front v3 の形(イメージ)

typedef struct FreeRouteSnapshotV3 {
    uint8_t route_kind[NUM_SMALL_CLASSES]; // enum free_route_kind_t
    // v6/v3/pool/legacy 向けの補助情報policy pointer 等)は別テーブルで
} FreeRouteSnapshotV3;

const FreeRouteSnapshotV3* free_front_v3_snapshot_get(void);

void hak_free(void* ptr) {
    uint8_t header = *(uint8_t*)((uintptr_t)ptr - 1);
    uint32_t class_idx = header & HEADER_CLASS_MASK;

    const FreeRouteSnapshotV3* snap = free_front_v3_snapshot_get();
    free_route_kind_t route = snap->route_kind[class_idx];

    switch (route) {
    case FREE_ROUTE_TINY_V3:
        hak_tiny_free_fast_v3(ptr, class_idx, snap);
        return;
    case FREE_ROUTE_CORE_V6_C6:
        small_free_fast_v6(ptr, class_idx, small_heap_ctx_v6(),
                           snap->core_v6_policy);
        return;
    case FREE_ROUTE_POOL_V1:
        hak_pool_free(ptr, 0, 0);
        return;
    // ... 他ルートULTRA, legacy など)
    }
}

ここでは:

  • header→class_idx→route_kind が front v3 の責務。
  • route_kind に v6/v3/pool/legacy の組み合わせや ENV の影響がすべて反映される。
  • 下流の箱v6/v3/poolは「自分の free を実行する」ことだけに集中できる。

FREE-FRONT-V3-0 のゴール

このドキュメントでは、以下を設計レベルで固定する:

  • 現状 free front のスタックと perf 上のボトルネックroute 二重チェック、ENV 多段チェック、lookup の位置)。
  • free front v3 で目指す構造header 読みclass_idx 判定snapshot route 決定1回の dispatch
  • 以降のフェーズで:
    • free_front_v3_env_box.h のような ENV→snapshot 初期化箱を作る。
    • hak_free に free front v3 の接続を 1 箇所だけ差し込む。
    • Mixed で free/gate の self% を A/B 測定する。

実装は次フェーズFREE-FRONT-V3-1 以降)のタスクとし、ここでは「どこを削るか」「どこを HotPath から外すか」の設計を記録する。