Files
hakmem/docs/analysis/SMALLOBJECT_V4_BOX_DESIGN.md
Moe Charm (CI) dd974b49c5 Phase v4-mid-2, v4-mid-3, v4-mid-5: SmallObject HotBox v4 implementation and docs update
Implementation:
- SmallObject HotBox v4 (core/smallobject_hotbox_v4.c) now fully implements C6-only allocations and frees, including current/partial management and freelist operations.
- Cold Iface (tiny_heap based) for page refill/retire is integrated.
- Stats instrumentation (v4-mid-5) added to small_heap_alloc_fast_v4 and small_heap_free_fast_v4, with a new header file core/box/smallobject_hotbox_v4_stats_box.h and atexit dump function.

Updates:
- CURRENT_TASK.md has been condensed and updated with summaries of Phase v4-mid-2 (C6-only v4), Phase v4-mid-3 (C5-only v4 pilot), and the stats implementation (v4-mid-5).
- docs/analysis/SMALLOBJECT_V4_BOX_DESIGN.md updated with A/B results and conclusions for C6-only and C5-only v4 implementations.
- The previous CURRENT_TASK.md content has been archived to CURRENT_TASK_ARCHIVE_20251210.md.
2025-12-11 01:01:15 +09:00

12 KiB
Raw Blame History

SmallObject HotBox v4 Box Design (Phase v4-1 スケルトン)

Overview

  • 目的: 16〜1024B〜2KiB の small-object を統合する v4 の箱を用意し、v3 の成功パターンC7-onlyを一般化する足場を作る。
  • 中期目標: mimalloc の 70〜80% に迫ること。現状は C7-only v3 + front v3 + fast classify で Mixed 161024B がまだ 30〜40% 程度。
  • 位置付け: v3 = prototype、v2 = archiveインターフェース参考のみ。v4 は構造を整理しつつホット/コールド境界を明確にする。

Box 構造

  • HotBox_v4: per-thread SmallHeapCtxSmallClassHeap[current/partial/full]SmallPageMeta を持つ。ホットパスはここに閉じ込める。
  • ColdIface_v4: refill_page / retire_page / remote_push / remote_drain を 1 箱に集約し、内部で Superslab / Warm / Remote を呼ぶ薄いラッパ。
  • SuperslabBox / RemoteBox: 既存の Superslab/WarmPool/Remote を Cold 側の箱として再利用Hot から直接触らない)。
  • PolicyBox / LearningBox: small-object 用の SmallPolicySnapshotblock_size/route_kind 等を上位で更新し、Hot は snapshot を読むだけにする。

Phase ロードマップ

  • v4-1: 型と入口だけ追加。挙動は v3/v1 のままで、コンパイルが通る足場を用意。
  • v4-2: C7-only を v4 に寄せ、v3 互換の挙動で動かすENV ゲート付き、v4 が優先)。
  • v4-3: C7-only を v4 自前の freelist/current/partial で動かすCold は Tiny v1 経由。v3 はベンチ用に残し ENV で A/B。
  • v4-3.1 (今回): C7 v4 で current/partial 再利用を強化し、prepare_calls を v3 並みに抑制。C7-only ベンチで v4 が v3 比 +1% 程度まで回復。
  • v4-4: C6 v4 パイロットC6-heavy 専用 opt-in。C7 v4 を維持しつつ C6 を v4 に載せる。
  • v4-5: C5 v4 パイロットC5-heavy 専用 opt-in。Mixed 標準は C5 v1 のまま。
  • PF2 (今回): v4 状態での pf/OS ベースライン取得と small-object Segment Box の箱だけ追加(挙動不変)。
  • v4-6 / PF3 以降: Segment/Page/Block レイアウトと pf 削減、WarmPool チューニングを v4 用に調整。

現行 v3/v2 の扱い

  • v3: C7-only front v3 の prototype として構造だけ再利用する。性能・安定のベースライン。
  • v2: archive として残し、インターフェース案のみ参照。ホットパスには混ぜない。

次ステップの入口

  • core/box/smallobject_hotbox_v4_box.h: v4 のページ/クラス/TLS 型と TLS アクセサ宣言。
  • core/box/smallobject_cold_iface_v4.h: ColdIface の関数ポインタ箱C7 専用 refill/retire を v1 Tiny に繋ぐ)。
  • core/box/tiny_route_env_box.h: TINY_ROUTE_SMALLHEAP_V4 を追加し、ENV HAKMEM_SMALL_HEAP_V4_ENABLED / HAKMEM_SMALL_HEAP_V4_CLASSES から C7 を v4 route に載せられる(未指定なら OFF
  • core/front/malloc_tiny_fast.h: route switch に v4 の case を足し、C7 v4 が ON のときは v4 経路(現在は C7 自前 freelist, それ以外は v1/v3 へフォールバック、OFF 時は従来の v3/v1。
  • core/box/smallsegment_v4_box.h / core/box/smallsegment_v4_env_box.h: PF2 で追加した small-object Segment Box の足場(型と ENV だけ、挙動不変)。設計メモは docs/analysis/SMALLOBJECT_SEGMENT_V4_DESIGN.md にまとめる。

A/B と運用2025-12 時点の整理)

  • v4 C7/C6/C5 はいずれも 研究箱。Mixed の標準ラインは C7-only v3 + C7 ULTRAUF-3 セグメントで固定し、v4 系は ENV opt-in のみで利用する。
  • C6/FREEZE 方針により、C6 v4 / C5 v4 は mid/pool 再設計が進むまで本線に載せないC6 は「普通の mid クラス」として pool/mid 側で扱う)。
  • 今後 small-object v4 を攻めるときは:
    • まず C7 ULTRA で固めた設計Segment + Page + TLS freelist + mask freeを「small-object 全体の共通パターン」として整理し、
    • その上で 16〜2KiB 帯を SmallHeapCtx v4 に寄せるヘッダレス化・lookup 削減を C7 と mid で統合)、 という順番で進める。

Phase v4-mid-design: mid/small-object 帯をどう乗せるか

方針サマリ

  • 目標: 16〜2KiB 帯の small-object/mid を SmallObjectHotBox_v4 に集約し、Mixed 16〜1024B を mimalloc の 5 割50〜60M ops/sに近づける。
  • Hot/Cold/Policy の分離は C7 ULTRA と同様に維持する:
    • Hot: per-thread SmallHeapCtxSmallClassHeap + SmallPageMetaで alloc/free を完結。
    • Cold: SmallColdIface_v4 から SmallSegmentBox_v4 / SuperslabBox / RemoteBox に橋渡し。
    • Policy/Learning: SmallPolicySnapshot を上位箱が更新し、Hot は route_kind や block_size を読むだけ。
  • C7 ULTRA は「C7 専用 TLS/Segment lane」として維持し、mid/small-object 帯は SmallHeapCtx v4 に寄せる形で共存させる。

HotBox_v4SmallHeapCtxのイメージ

typedef struct SmallPageMeta {
    void*     free_list;   // block → next pointer
    uint16_t  used;        // 現在使用中
    uint16_t  capacity;    // スロット数
    uint8_t   class_idx;   // サイズクラス (small-object 帯)
    uint8_t   flags;       // HOT/PARTIAL/FULL/REMOTE_PENDING など
    uint16_t  page_idx;    // セグメント内 index
    void*     segment;     // SmallSegment* back pointer
} SmallPageMeta;

typedef struct SmallClassHeap {
    SmallPageMeta* current;
    SmallPageMeta* partial_head;
    SmallPageMeta* full_head;
} SmallClassHeap;

typedef struct SmallHeapCtx {
    SmallClassHeap cls[NUM_SMALL_CLASSES]; // 16〜2KiB を covering
} SmallHeapCtx;
  • HotPath:
    • alloc: size→class_idxLUTroute_kind==SMALL_V4 なら SmallHeapCtx 経由で current→partial→cold_refill の順に見る。
    • free: small_page_meta_of(ptr)SegmentBox v4 が提供)→ owner/self 判定 → local free or remote_push。
  • C7 ULTRA:
    • ptr が ULTRA segment 上にある場合のみ ULTRA lane を通り、それ以外は SmallHeap v4 / 既存 v3 にフォールバックするオーバーレイ構造を維持。

SmallSegmentBox_v4 と ptr→page→class の O(1) 解決

  • C7 ULTRA で使っている 2MiB Segment + 64KiB Page を multi-class small-object 用に拡張:
#define SMALL_SEGMENT_SIZE   (2 * 1024 * 1024)
#define SMALL_PAGE_SIZE      (64 * 1024)

typedef struct SmallSegment {
    uintptr_t      base;
    uint32_t       num_pages;
    uint32_t       owner_tid;
    uint32_t       magic;
    SmallPageMeta  page_meta[SMALL_SEGMENT_SIZE / SMALL_PAGE_SIZE];
} SmallSegment;
  • ptr→page_meta の計算:
static inline SmallPageMeta* small_page_meta_of(void* p) {
    uintptr_t addr = (uintptr_t)p;
    uintptr_t seg_base = addr & ~(SMALL_SEGMENT_SIZE - 1);
    SmallSegment* seg = (SmallSegment*)seg_base;
    // magic で small segment か確認Fail-Fast
    size_t page_idx = (addr - seg_base) >> SMALL_PAGE_SHIFT; // 64KiB page
    if (page_idx >= seg->num_pages) return NULL;
    return &seg->page_meta[page_idx];
}
  • これにより mid/small-object 帯でも hak_super_lookup / mid_desc_lookup / classify_ptr / ss_map_lookup を HotPath から排除し、ptr→page→class を O(1) にできる。

ULTRA をどこまで広げるか

  • ULTRA パターン(専用 Segment + TLS freelist + mask freeは C7 では成功済み。
  • mid/smallmid では:
    • C7class7: 現状通り C7 ULTRA lane を利用。
    • 非常にホットな mid クラス(例: C6/C5が現れた場合のみ、ULTRA lane を追加する候補。
    • それ以外の small-object 帯は SmallHeapCtx v4multi-class heapに載せ、ULTRA は「1〜2 クラス専用 lane」として限定的に使う。
  • これにより:
    • RSS/fragmentation の増加を抑えつつ、
    • 「C7 ULTRA の勝ちパターン」を mid にも段階的に持ち込む余地を残せる。

フェーズ案mid/small-object v4 導入)

  1. Phase v4-mid-0:
    • SmallHeapCtx / SmallClassHeap / SmallPageMeta / SmallSegment の struct と SmallColdIface_v4 の関数シグネチャだけを追加(挙動は stub
    • HAKMEM_SMALL_HEAP_V4_ENABLED=0 時は一切 v4 コードを通らない。
  2. Phase v4-mid-1:
    • C6-only で route_kind=SMALL_V4_STUB にして、small_alloc_fast / small_free_fast は即 v1/pool にフォールバックしつつ、small_page_meta_of() の O(1) 判定だけ実装。
    • ptr→segment→page_meta の Fail-Fast を安定させる。
  3. Phase v4-mid-2:
    • C6-only で SmallHeap v4 を本実装page freelist / current/partial / refill/retireし、C6-heavy ベンチで v1/pool と A/B。
  4. Phase v4-mid-3:
    • Mixed 16〜1024B のうち一部クラス(例: C6, 次に C5を SMALL_V4 route に昇格。
    • Stats/Learning で hot クラスを観察しつつ、徐々に small-object 帯を v4 に寄せていく。

Learning/Stats 境界の注意

  • Stats は page/segment 単位で集計し、HotPath では page->used++/-- 以外を触らないretire/refill 時に Cold 側で aggregate
  • Learning は StatsBox から SmallPolicySnapshot を生成し:
    • route_kind[class]
    • block_size[class]
    • max_partial_pages[class] を更新するだけ。HotBox_v4 側は snapshot を読むだけに留める。

Phase v4-mid-2: C6-only SmallHeapCtx v4 本実装完了 (2025-12-10)

実装内容

  • core/smallobject_hotbox_v4.c に C6 用 SmallHeapCtx v4 を本格稼働:
    • small_heap_alloc_fast_v4(): current freelist → partial head → cold_refill の順で探索。
    • small_heap_free_fast_v4(): v4_find_page で page を特定 → freelist push → used==0 なら partial に温存 or retire。
  • Cold Iface (small_cold_v4_refill_page / small_cold_v4_retire_page) は tiny_heap 経由で動作済み。
  • Segment 関連 (smallsegment_v4_*) は tiny_heap を利用して page lease/retire を実装。

A/B 結果C6-heavy 257768B, 1 thread, ws=400, iters=1M

構成 Throughput (ops/s) 備考
v4 OFF (baseline) 9.13M 9.79M 平均 ~9.36M
v4 ON (C6-only) 10.00M 10.30M 平均 ~10.15M
改善 +8〜9% segv/assert なし

Mixed への影響161024B, ws=400, iters=1M

構成 Throughput (ops/s)
v4 OFF 29.66M
v4 ON (C6-only) 29.96M (+1%)

→ 大きな回帰なし、研究箱として安全。

ENV 設定例

HAKMEM_PROFILE=C6_HEAVY_LEGACY_POOLV1 \
HAKMEM_SMALL_HEAP_V4_ENABLED=1 \
HAKMEM_SMALL_HEAP_V4_CLASSES=0x40 \
./bench_mid_large_mt_hakmem 1 1000000 400 1

次ステップ

  • Phase v4-mid-3: C5 v4 パイロット、または Mixed の一部クラスを SMALL_V4 route に昇格させて A/B。

Phase v4-mid-3: C5-only v4 研究箱 A/B (2025-12-11)

実装内容

  • C5 (256B class) は既に v4_class_supported() で許可済み。コード変更は不要。
  • ENV HAKMEM_SMALL_HEAP_V4_CLASSES=0x20 で C5 v4 を有効化。

A/B 結果

C5-heavy (129256B, ws=400, iters=1M)

構成 Throughput (ops/s) 備考
v4 OFF 53.6M 55.4M 平均 ~54.4M
v4 ON (C5-only 0x20) 47.6M 49.5M 平均 ~48.7M
結果 10〜11% 回帰 既存 Tiny/front v3 経路が速い

Mixed 161024B (C5+C6 v4)

構成 Throughput (ops/s)
C6-only v4 (0x40) 27.5M 29.3M (平均 ~28.3M)
C5+C6 v4 (0x60) 28.3M 29.4M (平均 ~28.9M)
結果 +2〜3% (誤差〜微改善)

方針

  • C5-heavy では v4 が既存経路より劣後するため、C5 v4 は研究箱のまま標準プロファイルには入れない。
  • Mixed では影響が小さく回帰なし。C5+C6 v4 (0x60) は研究箱として安全に利用可能。
  • C5 サイズ帯は既存 Tiny/front v3 経路が十分最適化されており、v4 へ寄せるメリットは薄い。
  • 今後の small-object v4 拡張は C6-heavy / mid 帯に集中する。