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

211 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 `SmallHeapCtx``SmallClassHeap[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 用の `SmallPolicySnapshot`block_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 `SmallHeapCtx`SmallClassHeap + 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のイメージ
```c
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_idx`LUT`route_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 用に拡張:
```c
#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 の計算:
```c
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 設定例
```bash
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 帯に集中する。