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

8.9 KiB
Raw Blame History

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_SIMPLEHAKMEM_DEBUG_VERBOSEHAKMEM_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) -> boolowner_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/0publish/adopt 全体の ON/OFF
    • HAKMEM_TINY_RF_FORCE_NOTIFY=1(初回通知の見逃し検出)
    • HAKMEM_TINY_MAILBOX_SLOWDISC(_PERIOD)(遅延登録の発見)
    • HAKMEM_TINY_MUST_ADOPT=1mmap 直前の採用ゲート)

最小テスト(箱単位の 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/リングとワンショットログで芯を掴んでから上に進む。