Files
hakmem/AGENTS.md
Moe Charm (CI) 52386401b3 Debug Counters Implementation - Clean History
Major Features:
- Debug counter infrastructure for Refill Stage tracking
- Free Pipeline counters (ss_local, ss_remote, tls_sll)
- Diagnostic counters for early return analysis
- Unified larson.sh benchmark runner with profiles
- Phase 6-3 regression analysis documentation

Bug Fixes:
- Fix SuperSlab disabled by default (HAKMEM_TINY_USE_SUPERSLAB)
- Fix profile variable naming consistency
- Add .gitignore patterns for large files

Performance:
- Phase 6-3: 4.79 M ops/s (has OOM risk)
- With SuperSlab: 3.13 M ops/s (+19% improvement)

This is a clean repository without large log files.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 12:31:14 +09:00

156 lines
8.9 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.

# AGENTS: 箱理論Box Theory設計ガイドライン
本リポジトリでは、変更・最適化・デバッグを一貫して「箱理論Box Theory」で進めます。すべてを“箱”で分け、境界で接続し、いつでも戻せるように積み上げることで、複雑性を抑えつつ失敗コストを最小化します。
---
## 何が効くのか(実績)
- ❌ Rust/inkwell: 複雑なライフタイム管理
- ✅ 箱理論適用: 650行 → 100行SSA構築
なぜ効果があるか:
- PHI/Block/Value を「箱」として扱い、境界変換点を1箇所に集約
- 複雑な依存関係を箱の境界で切ることで単体検証が容易
- シンプルな Python/llvmlite で 2000行で完結道具に依存せず“箱”で分割して繋ぐ
補足C 実装時の利点)
- C の場合は `static inline` により箱間のオーバーヘッドをゼロに近づけられる(インライン展開)
---
## 🎯 AI協働での合言葉5原則
1. 「箱にする」: 設定・状態・橋渡しは Box 化
- 例: TLS 状態、SuperSlab adopt、remote queue などは役割ごとに箱を分離
2. 「境界を作る」: 変換は境界1箇所で
- 例: adopt → bind、remote → freelist 統合、owner 移譲などの変換点を関数1箇所に集約
3. 「戻せる」: フラグ・feature で切替可能に
- `#ifdef FEATURE_X` / 環境変数 で新旧経路を A/B 可能に(回帰や切り戻しを即時化)
4. 「見える化」: ダンプ/JSON/DOT で可視化
- 1回だけのワンショットログ、統計カウンタで“芯”を掴む常時ログは避ける
5. 「Fail-Fast」: エラー隠さず即座に失敗
- ENOMEM/整合性違反は早期に露呈させる(安易なフォールバックで隠さない)
要するに: 「すべてを箱で分けて、いつでも戻せるように積み上げる」設計哲学にゃ😺🎁
---
## 適用ガイド(このリポジトリ)
- 小さく積むBox 化)
- Remote Free Queue, Partial SS Adopt, TLS Bind/Unbind を独立した“箱”として定義
- 箱の API は最小・明確init/publish/adopt/drain/bind など)
- 境界は1箇所
- Superslab 再利用の境界は `superslab_refill()` に集約publish/adopt の接点)
- Free の境界は “same-thread / cross-thread” の判定1回
- 切替可能(戻せる)
- 新経路は `#ifdef` / 環境変数でオンオフA/B と回帰容易化)
- 例: `HAKMEM_TINY_PHASE6_ULTRA_SIMPLE``HAKMEM_DEBUG_VERBOSE``HAKMEM_TINY_*` env
- 見える化(最小限)
- 1回だけのデバッグ出力ワンショットと統計カウンタで芯を掴む
- 例: [SS OOM]、[SS REFILL] のワンショットログ、alloc/freed/bytes の瞬間値
- Fail-Fast
- ENOMEM・整合性違反はマスクせず露出。フォールバックは“停止しないための最後の手段”に限定
---
## 実装規約C向けの具体
- `static inline` を多用し箱間の呼び出しをゼロコスト化
- 共有状態は `_Atomic` で明示、CAS ループは局所化MPSC push/pop はユーティリティ化)
- 競合制御は「箱の内側」に閉じ込め、外側はシンプルに保つ
- 1つの箱に 1つの責務publish/adopt、drain、bind、owner 移譲 など)
---
## チェックリストPR/レビュー時)
- 箱の境界は明確か変換点が1箇所に集約されているか
- フラグで戻せるかA/B が即時に可能か)
- 可視化のフックは最小か(ワンショット or カウンタ)
- Fail-Fast になっているか(誤魔化しのフォールバックを入れていないか)
- C では `static inline` でオーバーヘッドを消しているか
---
この AGENTS.md は、箱理論の適用・コーディング・デバッグ・A/B 評価の“共通言語”です。新しい最適化や経路を足す前に、まず箱と境界を設計してから手を動かしましょう。
---
## Tiny 向け「積み方 v2」(層を下から固める)
下層の箱が壊れている状態で上層を積むと必ず崩れます。まず下から順に箱を“堅牢化”してから上を載せる、を徹底します。
層と責務
- Box 1: Atomic Ops (最下層)
- 役割: `stdatomic.h` による CAS/Exchange の秩序付けAcquire/Release
- ルール: メモリ順序を箱内で完結させる(外側に弱い順序を漏らさない)。
- Box 2: Remote Queue (下層)
- 役割: cross-thread free の MPSC スタックpush/exchangeとカウント管理。
- API: `ss_remote_push(ss, slab_idx, ptr) -> transitioned(0/1)``ss_remote_drain_to_freelist(ss, slab_idx)``ss_remote_drain_light(ss)`
- 不変条件 (Invariants):
- push はノードの next を書き換える以外に副作用を持たないfreelist/owner へは触れない)。
- head は SuperSlab 範囲内Fail-Fast 範囲検証)。
- `remote_counts[s]` は push/drain で単調に整合するdrain 後は 0
- 境界: freelist への統合は必ず drain 関数内1 箇所。publish/adopt からの直接 drain は禁止。
- Box 3: Ownership (中層)
- 役割: slab の所有者遷移(`owner_tid`)。
- API: `ss_owner_try_acquire(meta, tid) -> bool``owner_tid==0` の時のみ CAS で取得)、`ss_owner_release(meta, tid)``ss_owner_is_mine(meta, tid)`
- 不変条件:
- Remote Queue は owner に触らないBox 2→3 への侵入禁止)。
- Acquire 成功後のみ “同一スレッド” の高速経路を使用する。
- 境界: bind 時にのみ acquire/release を行う(採用境界 1 箇所)。
- Box 4: Publish / Adopt (上層)
- 役割: 供給の提示publishと消費adopt
- API: `tiny_publish_notify(class, ss, slab)``tiny_mailbox_publish()``tiny_mailbox_fetch()``ss_partial_publish()``ss_partial_adopt()`
- 不変条件:
- publish は “通知とヒント” のみfreelist/remote/owner に触れない)。
- `ss_partial_publish()` は unsafe drain をしない。必要なら drain は採用側境界で実施。
- publish 時に `owner_tid=0` を設定してもよいが、実際の acquire は採用境界でのみ行う。
- 境界: adopt 成功直後にだけ `drain → bind → owner_acquire` を行う(順序は必ずこの 1 箇所)。
実装ガイド(境界の 1 か所化)
- Refill 経路(`superslab_refill()` / `tiny_refill_try_fast()`)でのみ:
1) sticky/hot/bench/mailbox/reg を “peek して” 候補を得る
2) 候補が見つかったら当該 slab で `ss_remote_drain_to_freelist()` を 1 回だけ実行(必要時)
3) freelist が非空であれば `tiny_tls_bind_slab()``ss_owner_try_acquire()` の順で確定
4) 確定後にのみ publish/overflow は扱う(不要な再 publish/drain はしない)
Do / Dont壊れやすいパターンの禁止
- Dont: Remote Queue から publish を直接呼ばない条件分岐を増やす(通知の濫用)。
- Dont: publish 側で drain / owner をいじる。
- Do: Remote Queue は push と count 更新のみ。publish は通知のみ。採用境界で drain/bind/owner を一度に行う。
デバッグ・トリアージ順序FailFast
1) Box 2Remote単体: push→drain→freelist の整合をアサート(範囲検証 ON, `remote_counts` 符合)。
2) Box 3Ownership単体: `owner_tid==0` からの acquire/release を並行で連続試験。
3) Box 4Publish/Adopt単体: publish→mailbox_register/fetch の通電fetch ヒット時のみ adopt を許可)。
4) 全体: adopt 境界でのみ `drain→bind→owner_acquire` を踏んでいるかリングで確認。
可視化と安全化(最小構成)
- Tiny Ring: `TINY_RING_EVENT_REMOTE_PUSH/REMOTE_DRAIN/MAILBOX_PUBLISH/MAILBOX_FETCH/BIND` を採用境界前後に記録。
- EnvA/B・切戻し:
- `HAKMEM_TINY_SS_ADOPT=1/0`publish/adopt 全体の ON/OFF
- `HAKMEM_TINY_RF_FORCE_NOTIFY=1`(初回通知の見逃し検出)
- `HAKMEM_TINY_MAILBOX_SLOWDISC(_PERIOD)`(遅延登録の発見)
- `HAKMEM_TINY_MUST_ADOPT=1`mmap 直前の採用ゲート)
最小テスト(箱単位の smoke
- Remote Queue: 同一 slab へ N 回 `ss_remote_push()``ss_remote_drain_to_freelist()``remote_counts==0` と freelist 長の一致。
- Ownership: 複数スレッドで `ss_owner_try_acquire()` の成功が 1 本だけになること、`release` 後に再取得可能。
- Publish/Mailbox: `tiny_mailbox_publish()``tiny_mailbox_fetch()` のヒットを 1 回保証。`fetch_null` のとき `used` 拡張が有効。
運用の心得
- 下層Remote/Ownershipに疑義がある間は、上層Publish/Adoptを “無理に” 積み増さない。
- 変更は常に A/B ガード付きで導入し、SIGUSR2/リングとワンショットログで芯を掴んでから上に進む。