Updated documentation to reflect commit 6b791b97d deletions:
Removed ENV variables (6):
- HAKMEM_TINY_ULTRA_FRONT
- HAKMEM_TINY_ULTRA_L0
- HAKMEM_TINY_ULTRA_HEAP_DUMP
- HAKMEM_TINY_ULTRA_PAGE_DUMP
- HAKMEM_TINY_BG_REMOTE (no getenv, dead code)
- HAKMEM_TINY_BG_REMOTE_BATCH (no getenv, dead code)
Files updated (5):
- docs/analysis/ENV_CLEANUP_ANALYSIS.md: Updated BG/Ultra counts
- docs/analysis/ENV_QUICK_REFERENCE.md: Updated verification sections
- docs/analysis/ENV_CLEANUP_PLAN.md: Added REMOVED category
- docs/archive/TINY_LEARNING_LAYER.md: Added archive notice
- docs/archive/MAINLINE_INTEGRATION.md: Added archive notice
Changes: +71/-32 lines
Preserved ENV variables:
- HAKMEM_TINY_ULTRA_SLIM (active 4-layer fast path)
- HAKMEM_ULTRA_SLIM_STATS (Ultra SLIM statistics)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
13 KiB
Tiny Learning Layer & Backend Integration (Phase 27 Snapshot)
⚠️ ARCHIVE NOTICE (2025-11-26) Several ENV variables and files referenced in this document were removed in commit
6b791b97d:
HAKMEM_TINY_ULTRA_FRONT(deleted)HAKMEM_TINY_ULTRA_L0(deleted)HAKMEM_TINY_ULTRA_HEAP_DUMP(deleted)HAKMEM_TINY_ULTRA_PAGE_DUMP(deleted)HAKMEM_TINY_BG_REMOTE(deleted)HAKMEM_TINY_BG_REMOTE_BATCH(deleted)- Files deleted:
core/front/tiny_ultrafront.h,core/ultra/tiny_ultra_heap.c,core/ultra/tiny_ultra_page_arena.cThis document is kept for historical reference but may contain outdated information.
Date: 2025-11-21 Scope: Tiny (0–1KB) / Shared Superslab Pool / FrozenPolicy / Ultra* Boxes Goal: 学習層(FrozenPolicy / Learner)を活かして、Tiny の backend を「自動でそれなりに最適」な状態に保つための箱と境界を整理する。
1. Box Topology(Tiny 向けの学習レイヤ構成)
-
Box SP-SLOT (SharedSuperSlabPool)
- ファイル:
core/hakmem_shared_pool.{h,c},core/superslab/superslab_types.h - 役割:
- Tiny クラス 0..7 向けの Superslab を 共有プールとして管理(per-class SuperSlabHead legacy を徐々に退役)。
- Slot state:
SLOT_UNUSED / SLOT_ACTIVE / SLOT_EMPTYを per-slab で追跡。
- 主要フィールド:
_Atomic uint64_t g_sp_stage1_hits[cls]… EMPTY 再利用 (Stage1)_Atomic uint64_t g_sp_stage2_hits[cls]… UNUSED claim (Stage2)_Atomic uint64_t g_sp_stage3_hits[cls]… 新規 SuperSlab (Stage3)uint32_t class_active_slots[TINY_NUM_CLASSES_SS]… クラス別 ACTIVE slot 数
- 主要 API:
shared_pool_acquire_slab(int class_idx, SuperSlab** ss, int* slab_idx)shared_pool_release_slab(SuperSlab* ss, int slab_idx)
- ENV:
HAKMEM_SHARED_POOL_STAGE_STATS=1
→ プロセス終了時に Stage1/2/3 の breakdown を 1 回だけダンプ。
- ファイル:
-
Box TinySuperslab Backend Box (
hak_tiny_alloc_superslab_box)- ファイル:
core/hakmem_tiny_superslab.{h,c} - 役割:
- Tiny front(Unified / UltraHeap / TLS)から Superslab backend への 唯一の出入口。
- shared backend / legacy backend / hint Box を 1 箇所で切り替える。
- Backend 実装:
hak_tiny_alloc_superslab_backend_shared(int class_idx)
→ Shared Pool / SP-SLOT 経由。hak_tiny_alloc_superslab_backend_legacy(int class_idx)
→ 旧SuperSlabHeadベース(回帰・fallback 用)。hak_tiny_alloc_superslab_backend_hint(int class_idx)
→ legacy に落ちる前に、直近の (ss, slab_idx) を 1 回だけ再利用する軽量 Box。
- ENV:
HAKMEM_TINY_SS_SHARED=0
→ 強制 legacy backend のみ。HAKMEM_TINY_SS_LEGACY_FALLBACK=0
→ shared 失敗時にも legacy を使わない(完全 Unified モード)。HAKMEM_TINY_SS_C23_UNIFIED=1
→ C2/C3 だけ legacy fallback を無効化(他クラスは従来どおり shared+legacy)。HAKMEM_TINY_SS_LEGACY_HINT=1
→ shared 失敗 → legacy の間に hint Box を挟む。
- ファイル:
-
Box FrozenPolicy / Learner(学習層)
- ファイル:
core/hakmem_policy.{h,c},core/hakmem_learner.c - 役割:
- Mid/Large で実績がある CAP/W_MAX 調整ロジックを Tiny に拡張する足場。
- Tiny 向けフィールド:
uint16_t tiny_cap[8]; // classes 0..7
→ Shared Pool の「クラス別 ACTIVE slot 上限」(soft cap)。
- Tiny CAP デフォルト(Phase 27 時点):
{2048, 1024, 96, 96, 256, 256, 128, 64}
→ C2/C3 は Shared Pool 実験対象として 96/96 に設定。
- ENV:
HAKMEM_CAP_TINY=2048,1024,96,96,256,256,128,64
→ 先頭から 8 個をtiny_cap[0..7]に上書き。
- ファイル:
-
Box UltraPageArena(Tiny→Page 層の観察箱)
- ファイル:
core/ultra/tiny_ultra_page_arena.{h,c} - 役割:
superslab_refill(int class_idx)をフックし、クラス別の Superslab refill 回数をカウント。
- API:
tiny_ultra_page_on_refill(int class_idx, SuperSlab* ss)tiny_ultra_page_stats_snapshot(uint64_t refills[8], int reset)
- ENV:
HAKMEM_TINY_ULTRA_PAGE_DUMP=1
→ 終了時に[ULTRA_PAGE_STATS]を 1 回だけダンプ。
- ファイル:
2. 学習ループに見せるメトリクス
Tiny 学習層が見るべきメトリクスと取得元:
-
Active Slot / CAP 関連
g_shared_pool.class_active_slots[class]
→ クラス別 ACTIVE slot 数(Shared Pool 管理下)。FrozenPolicy.tiny_cap[class]
→ soft cap。shared_pool_acquire_slabStage3 でcur >= capなら 新規 Superslab 拒否。
-
Acquire Stage 内訳
g_sp_stage1_hits[class]… Stage1 (EMPTY slot 再利用)g_sp_stage2_hits[class]… Stage2 (UNUSED slot claim)g_sp_stage3_hits[class]… Stage3 (新規 SuperSlab / LRU pop)- これらの合算から:
- Stage3 割合が高い → Superslab churn が多い、CAP/Precharge/LRU を増やす候補。
- Stage1 が長期間 0% → EMPTY スロットがほぼ生成されていない(free 側のポリシー改善候補)。
-
Page 層イベント
TinyUltraPageStats.superslab_refills[cls]
→ クラス別の refill 回数。Tiny front から見た「page 層イベントの多さ」を測る。
3. 現状のポリシーと挙動(Phase 27)
3.1 Shared Pool backend 選択
hak_tiny_alloc_superslab_box(int class_idx) のポリシー:
-
HAKMEM_TINY_SS_SHARED=0のとき:- 常に legacy backend (
hak_tiny_alloc_superslab_backend_legacy) のみを使用。
- 常に legacy backend (
-
shared 有効時:
- 基本経路:
p = hak_tiny_alloc_superslab_backend_shared(class_idx);p != NULLならそのまま返す。
- fallback 判定:
HAKMEM_TINY_SS_LEGACY_FALLBACK=0
→ shared 失敗でも legacy へは落とさず、そのままNULL許容(完全 Unified モード)。HAKMEM_TINY_SS_C23_UNIFIED=1
→ C2/C3 の場合に限りlegacy_fallback=0に上書き(他クラスはg_ss_legacy_fallbackに従う)。
- hint Box:
- shared 失敗 & fallback 許可時に限り:
hak_tiny_alloc_superslab_backend_hint(class_idx)を 1 回だけ試す。- 直近成功した
(ss, slab_idx)がまだused < capacityなら、そこから 1 ブロックだけ追加 carve。
- shared 失敗 & fallback 許可時に限り:
- 基本経路:
3.2 FrozenPolicy.tiny_cap と Shared Pool の連携
shared_pool_acquire_slab()Stage3(新規 Superslab 確保)直前に:uint32_t limit = sp_class_active_limit(class_idx); // = tiny_cap[class] uint32_t cur = g_shared_pool.class_active_slots[class_idx]; if (limit > 0 && cur >= limit) { return -1; // Soft cap reached → caller 側で legacy fallback or NULL }- 意味:
tiny_cap[class]==0→ 制限なし(無限に Superslab を増やせる)。>0→ ACTIVE slot 数が cap に達したら 新規 SuperSlab を増やさない(churn 制御)。
現状のデフォルト:
{2048,1024,96,96,256,256,128,64}- C2/C3 を 96 に抑えつつ、C4/C5 は 256 slots まで許容。
- ENV
HAKMEM_CAP_TINYで一括上書き可能。
3.3 C2/C3 限定「ほぼ完全 Unified」実験
HAKMEM_TINY_SS_C23_UNIFIED=1のとき:- C2/C3:
- shared backend のみで運転(
legacy_fallback=0)。 - Shared Pool から Superslab/slab が取れなかった場合は
NULLを返し、上位が UltraFront/TinyFront 経路にフォールバック。
- shared backend のみで運転(
- 他クラス:
- 従来どおり shared+legacy fallback。
- C2/C3:
- Random Mixed 256B / 200K / ws=256 での挙動:
- デフォルト設定(C2/C3 cap=96): ≈16.8M ops/s 前後。
HAKMEM_TINY_SS_C23_UNIFIED=1の有無で差は ±数% レベル(ランダム揺らぎ内)。- OOM / SEGV は観測されず、C2/C3 を Shared Pool 単独で回す足場としては安定。
4. 「学習層を活かす」ための次ステップ(Tiny 向け)
今ある土台を使って、学習層を Tiny に伸ばすときの具体的なステップと現状:
-
Learner に Tiny メトリクスを配線(済)
core/hakmem_learner.cに Tiny 専用メトリクスを追加済み:active_slots[class] = g_shared_pool.class_active_slots[class];stage3_ratio[class] = ΔStage3 / (ΔStage1+ΔStage2+ΔStage3);refills[class] = tiny_ultra_page_global_stats_snapshot()から取得。
-
tiny_cap[] のヒルクライム調整(実装済み/チューニング中)
- 各 Tiny クラスごとに、ウィンドウ内の Stage3 割合を監視:
- Stage3 が多すぎ(新規 SuperSlab が頻発) →
tiny_cap[class]を +Δ。 - Stage3 が少ない & ACTIVE slot が少ない →
tiny_cap[class]を -Δ。
- Stage3 が多すぎ(新規 SuperSlab が頻発) →
- cap の下限は
max(min_tiny, active_slots[class])にクリップし、
既に確保済みの Superslab を急に「上限超過」にしないようにしている。 - 調整後は
hkm_policy_publish()で新しい FrozenPolicy を公開。
- 各 Tiny クラスごとに、ウィンドウ内の Stage3 割合を監視:
-
PageArena / Precharge / Cache との連携(TinyPageAuto, 実験中)
- UltraPageArena / SP-SLOT / PageFaultTelemetry からのメトリクスを使って、Superslab OS キャッシュ+precharge を軽く制御:
HAKMEM_TINY_PAGE_AUTO=1のとき、Learner が各ウィンドウでrefills[class](UltraPageArena の Superslab refill 数, C2〜C5)と- PageFaultTelemetry の
PF_pages(C2..C5)およびPF_pages(SSM)を読み取り、 score = refills * PF_pages(Cn) + PF_pages(SSM)/8を計算。
- スコアが
HAKMEM_TINY_PAGE_MIN_REFILLS * HAKMEM_TINY_PAGE_PRE_MIN_PAGES以上のクラスだけに対して:tiny_ss_precharge_set_class_target(class, target)(既定 target=1)で precharge を有効化。tiny_ss_cache_set_class_cap(class, cap)(既定 cap=2)で OS Superslab キャッシュ枚数を small cap に設定。
- スコアがしきい値未満のクラスは
target=0, cap=0に戻して OFF。
- これにより、Tiny 側から見て Superslab 層の「refill + PF が重いクラスだけ少数の Superslab を先行 fault-in / 温存」する挙動を学習層から制御できる状態まで到達している(まだパラメータ調整段階)。
- UltraPageArena / SP-SLOT / PageFaultTelemetry からのメトリクスを使って、Superslab OS キャッシュ+precharge を軽く制御:
-
Near-Empty しきい値の学習統合(C2/C3)
- Box:
TinyNearEmptyAdvisor(core/box/tiny_near_empty_box.{h,c})- free パスで C2/C3 の
TinySlabMeta.used/capから「near-empty slab」を検出し、イベント数を集計。 - ENV:
HAKMEM_TINY_SS_PACK_C23=1… near-empty 観測 ON。HAKMEM_TINY_NEAREMPTY_PCT=P… 初期しきい値 (%), 1〜99, 既定 25。HAKMEM_TINY_NEAREMPTY_DUMP=1… 終了時に[TINY_NEAR_EMPTY_STATS]を 1 回ダンプ。
- free パスで C2/C3 の
- Learner 側からの自動調整:
HAKMEM_TINY_NEAREMPTY_AUTO=1のとき、- ウィンドウ内で near-empty イベント(C2/C3 合計)が 0 の場合:
- しきい値 P を
+STEPだけ緩める(P_MAX まで、STEP 既定 5)。
- しきい値 P を
- near-empty イベントが多すぎる(例: 128 以上)の場合:
- P を
-STEPだけ締める(P_MIN まで)。
- P を
- P_MIN/P_MAX/STEP はそれぞれ
HAKMEM_TINY_NEAREMPTY_PCT_MIN(既定 5)HAKMEM_TINY_NEAREMPTY_PCT_MAX(既定 80)HAKMEM_TINY_NEAREMPTY_PCT_STEP(既定 5) で上書き可能。
- ウィンドウ内で near-empty イベント(C2/C3 合計)が 0 の場合:
- Random Mixed / Larson では near-empty イベント自体がほとんど発生しておらず、
現状は P がゆるやかに上限側へ寄るだけ(挙動への影響はごく小さい)。
- Box:
-
総合スコアでの最適化
- 1 ベンチ(例: Random Mixed 256B)ではなく:
- Fixed-size Tiny
- Random Mixed 各サイズ
- Larson / Burst / Apps 系 をまとめたスコア(平均 ops/s + メモリフットプリント + page fault)に対して、
- Tiny/Learning 層が CAP/Precharge/Cache を少しずつ動かすイメージ。
- 1 ベンチ(例: Random Mixed 256B)ではなく:
6. 既知の制限と安全策
- 8192B Random Mixed で発生していた TLS SLL head=0x60 問題は:
tls_sll_pop()内で head が低アドレスの場合に、そのクラスの SLL をリセットし slow path に逃がす形で 箱の内側で Fail-Fast させるように修正済み。- これにより、長尺ベンチでも SEGV せずに回し続けられる。
tiny_nextptr.hのtiny_next_store()には軽いガードを入れ、nextが 0 以外かつ<0x1000/>0x7fff...の場合に 1 回だけ[NEXTPTR_GUARD]を出すようにしてある(観測専用)。- 現時点の観測では C4 で一度だけ
next=0x47が記録されており、freelist/TLS 経路のどこかに残存バグがあることは認識済み。 - ただし Fail-Fast により箱の内側でリセットされるため、外側の挙動(ベンチ・アプリ)は安定している。
将来的に「完全退治」まで進める場合は、Tiny 向け debug ビルド構成を整えたうえで
NEXTPTR_GUARD の call site を addr2line などで特定し、当該経路をピンポイントに修正する予定。