2025-12-10 17:58:42 +09:00
|
|
|
|
# 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 16–1024B がまだ 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% 程度まで回復。
|
2025-12-10 19:14:38 +09:00
|
|
|
|
- **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 用に調整。
|
2025-12-10 17:58:42 +09:00
|
|
|
|
|
|
|
|
|
|
## 現行 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。
|
2025-12-10 19:14:38 +09:00
|
|
|
|
- `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` にまとめる。
|
2025-12-10 17:58:42 +09:00
|
|
|
|
|
2025-12-10 22:57:26 +09:00
|
|
|
|
## A/B と運用(2025-12 時点の整理)
|
|
|
|
|
|
- v4 C7/C6/C5 はいずれも **研究箱**。Mixed の標準ラインは C7-only v3 + C7 ULTRA(UF-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 で統合)、
|
|
|
|
|
|
という順番で進める。
|
2025-12-10 23:23:07 +09:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 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_v4(SmallHeapCtx)のイメージ
|
|
|
|
|
|
```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 では:
|
|
|
|
|
|
- C7(class7): 現状通り C7 ULTRA lane を利用。
|
|
|
|
|
|
- 非常にホットな mid クラス(例: C6/C5)が現れた場合のみ、ULTRA lane を追加する候補。
|
|
|
|
|
|
- それ以外の small-object 帯は SmallHeapCtx v4(multi-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 を読むだけに留める。
|
2025-12-11 01:01:15 +09:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 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 257–768B, 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 への影響(16–1024B, 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 (129–256B, 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 16–1024B (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 帯に集中する。
|