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>
11 KiB
全部動的大作戦: Ultrathink 戦略設計
🎯 作戦目的の明確化
Primary Goal: 状態適応型メモリ管理
コンセプト:
Static Allocation (現状):
├─ 起動時に大容量確保
├─ Idle時も保持
└─ メモリ無駄
Dynamic Allocation (目標):
├─ 必要時のみ確保
├─ Idle時は解放
└─ Workload適応
📊 目的の多角的分析
目的1: メモリ節約 ⭐⭐⭐⭐⭐
期待効果:
Scenario: Idle状態(allocation停止後)
Before (Static):
Mid Pool cache: ? MB (常時確保)
Large Pool cache: ? MB (常時確保)
Total overhead: 2-4 MB? (推定)
After (Dynamic):
Mid Pool cache: 0 MB (解放済み)
Large Pool cache: 0 MB (解放済み)
Total overhead: 0 MB
削減期待: -2-4 MB ✨
対象workload:
- Burst allocation → Idle cycle
- Short-lived server processes
- CLI tools(起動→処理→終了)
効果測定:
- Battle testでIdle時RSS測定
- smaps解析でcache overhead確認
目的2: Workload適応型容量 ⭐⭐⭐⭐
コンセプト:
Heavy workload:
Cache size: Large (performance重視)
Light workload:
Cache size: Small (memory重視)
Adaptive:
Allocation rate監視 → 動的調整
設計例:
// Adaptive cache sizing
int adaptive_cache_size(int class_idx) {
float rate = measure_alloc_rate(class_idx);
if (rate > HIGH_THRESHOLD) {
return MAX_CACHE_SIZE; // Performance mode
} else if (rate < LOW_THRESHOLD) {
return MIN_CACHE_SIZE; // Memory mode
} else {
return MEDIUM_CACHE_SIZE; // Balanced
}
}
メリット:
- Heavy: 性能維持
- Light: メモリ節約
- Best of both worlds!
デメリット:
- Rate測定コスト
- Tuning必要
- 複雑度増加
目的3: 速度向上の可能性 ⭐⭐⭐
仮説1: Cache hit率向上
Static (大容量固定):
Cache size: 2048 slots
Working set: 100 items
Hit rate: 100% (over-provisioned)
Memory waste: 95%
Dynamic (適応型):
Cache size: 128 slots (working setに合わせる)
Working set: 100 items
Hit rate: 98-100% (十分)
Memory waste: 22%
L1 cache locality: 向上! ✨
理由:
- 小さいcache → L1 cacheに収まる
- Locality向上 → アクセス高速化
- Phase 7-8のTiny Magazine過剰設計と同じ
期待効果: +3-5% throughput
仮説2: Fragmentation削減
Static:
Cache: 常に確保
Fragmentation: 増加傾向
Dynamic:
Cache: 定期的に解放・再確保
Fragmentation: 削減傾向
期待効果: Memory layout最適化
目的4: Idle時完全返却 ⭐⭐⭐⭐⭐
最重要目的!
現状問題:
Process終了前:
Total allocated: 0 (全てfree済み)
RSS: ? MB (cache overhead残存)
期待:
RSS should be: Baseline (~5 MB)
Gap: Cache overhead
動的化で解決:
// On idle detection or before exit
void release_all_caches(void) {
mid_pool_flush_all(); // Mid cache解放
large_pool_flush_all(); // Large cache解放
tiny_magazine_flush_all(); // Tiny Magazine解放
// Result: RSS → Baseline
}
効果:
- Long-running processes: メモリリーク防止
- CLI tools: Clean exit
- Containerized apps: Resource efficiency
⚖️ トレードオフ分析
メリット vs デメリット
メリット:
1. メモリ節約: -2-4 MB (Idle時)
2. Workload適応: Heavy/Light最適化
3. 速度向上可能性: +3-5% (locality)
4. Idle完全返却: Clean state
5. Fragmentation削減: Layout最適化
デメリット:
1. 管理コスト: Rate測定、調整ロジック
2. 複雑度: State管理、Adaptive logic
3. Re-allocation: Cache再構築コスト
4. Tuning: 閾値調整必要
5. デバッグ: 動的挙動の追跡困難
ROI分析
実装コスト:
- 調査: 1-2日
- 設計: 1日
- 実装: 2-3日
- テスト: 1-2日
- Total: 5-8日
期待リターン:
- メモリ: -2-4 MB
- 性能: ±0 ~ +5%
- 品質: Clean exit実現
ROI評価: ⭐⭐⭐⭐ (Good)
🔍 Phase 8調査の適用
Lesson 1: 想定を疑え
Phase 8教訓:
Magazine cache = 想定4MB、実測0.03MB(130倍誤差)
動的大作戦での適用:
想定:
Mid/Large cache overhead = 2-4 MB
実測必要項目:
□ 実際のcache size
□ 実使用率
□ Idle時の残存量
□ Re-allocation頻度
アクション: 実装前に徹底調査!
Lesson 2: smaps解析は必須
Phase 8成功要因:
- ru_maxrss → 見えない
- smaps → 真実発見
動的大作戦での適用:
測定項目:
1. Baseline overhead (起動直後)
2. Heavy workload時のcache overhead
3. Idle時のcache overhead
4. Flush後のRSS変化
ツール: investigate_smaps_detailed.c 再利用
Lesson 3: 段階的実装
Phase 8.1成功パターン:
Reserve 2 → 1 → 0
├─ Step 1: 2→1 測定
├─ Step 2: 1→0 測定
└─ 結論: 1が最適
動的大作戦での適用:
Step 1: Mid Pool動的化のみ
→ 効果測定
Step 2: Large Pool動的化追加
→ 効果測定
Step 3: Adaptive sizing追加
→ 効果測定
理由: 各ステップで効果を確認、ROI判断
🎯 動的大作戦の設計オプション
Option A: Simple Flush API (Phase 7.7パターン) ⭐⭐⭐⭐⭐
設計:
// Phase 7.7 Magazine Flush と同じパターン
void mid_pool_flush(void);
void large_pool_flush(void);
void pool_flush_all(void); // 全pool統合
トリガー:
- Manual call (test終了時)
- Idle detection (10ms無活動)
- Memory pressure (system signal)
メリット:
- 実装簡単(Phase 7.7の実績)
- リスク低
- 効果確実
デメリット:
- 完全自動化ではない
- Idle検出実装必要
期待効果: -2-4 MB (Idle時)
実装コスト: 1-2日
Option B: Adaptive Cache Sizing ⭐⭐⭐⭐
設計:
// Allocation rate監視
typedef struct {
uint64_t alloc_count;
uint64_t free_count;
uint64_t timestamp;
} PoolStats;
int adaptive_cache_size(PoolStats* stats) {
float rate = calculate_rate(stats);
if (rate > HIGH_THRESHOLD) {
return LARGE_CACHE; // Heavy workload
} else if (rate > MED_THRESHOLD) {
return MEDIUM_CACHE; // Normal
} else {
return SMALL_CACHE; // Light workload
}
}
メリット:
- Workload最適化
- Heavy時: 性能維持
- Light時: メモリ節約
デメリット:
- Rate測定コスト
- Tuning必要
- 複雑度高
期待効果:
- Memory: -1-2 MB (Light時)
- Performance: +3-5% (Heavy時、locality向上)
実装コスト: 3-4日
Option C: Time-based Shrinking ⭐⭐⭐⭐⭐
設計:
// 時間ベースのcache縮小
typedef struct {
void* cache;
size_t size;
uint64_t last_access_time;
} PoolCache;
void periodic_shrink_check(void) {
uint64_t now = get_time_ms();
for (each pool cache) {
if (now - cache.last_access_time > IDLE_THRESHOLD) {
shrink_cache(cache); // 段階的に縮小
}
}
}
トリガー: 定期的なbackground task (100ms毎)
メリット:
- 完全自動
- Gradual shrinking(急激な変化なし)
- Idle検出簡単
デメリット:
- Background task overhead
- Timer管理必要
期待効果: -2-3 MB (Idle時)
実装コスト: 2-3日
Option D: Hybrid (Flush + Adaptive) ⭐⭐⭐⭐⭐
設計:
// Option A + Option B
void pool_adaptive_flush(int pool_idx) {
PoolStats* stats = &g_pool_stats[pool_idx];
// Adaptive sizing決定
int target_size = adaptive_cache_size(stats);
int current_size = get_cache_size(pool_idx);
if (current_size > target_size) {
// 超過分をflush
shrink_to(pool_idx, target_size);
}
}
メリット:
- Best of both worlds
- Flush: 確実な解放
- Adaptive: 性能維持
デメリット:
- 複雑度最高
期待効果:
- Memory: -2-4 MB
- Performance: +3-5%
実装コスト: 4-5日
📋 推奨実装ロードマップ
Phase 1: 調査 (1-2日) ⭐⭐⭐⭐⭐
必須!(Phase 8教訓)
調査項目:
1. Mid/Large Pool実装確認
□ 現在のcache方式(static? dynamic?)
□ Cache size設定
□ 解放機構の有無
2. Overhead測定
□ Baseline (起動直後)
□ Heavy workload時
□ Idle時
□ smaps詳細解析
3. Re-allocation頻度測定
□ Cache hit/miss率
□ Re-alloc pattern分析
4. 改善余地評価
□ Static確保の無駄測定
□ 削減可能量推定
ツール:
investigate_smaps_detailed.c再利用- 新規: Mid/Large specific測定ツール
成果物:
- 現状分析レポート
- 削減可能量推定
- 実装方式決定
Phase 2: Simple Flush API (1-2日) ⭐⭐⭐⭐⭐
Phase 7.7パターン踏襲
実装:
void mid_pool_flush(void);
void large_pool_flush(void);
void pool_flush_all(void);
テスト:
- Battle test with flush
- smaps before/after比較
- 効果測定
判定基準:
- 削減量 > 1 MB → 成功
- 削減量 < 1 MB → 調査結果再評価
Phase 3: Adaptive (Optional, 2-3日) ⭐⭐⭐⭐
Phase 2効果次第で判断
条件:
- Phase 2削減量 > 2 MB
- 性能影響 < 5%
- さらなる最適化余地あり
実装:
- Option B or Option C
- Gradual deployment
🎯 成功基準
Minimum Success (Phase 2完了)
メモリ削減: -1-2 MB (Idle時)
性能影響: ±0%
実装コスト: 3-4日
ROI: ⭐⭐⭐⭐
Target Success (Phase 3完了)
メモリ削減: -2-4 MB (Idle時)
性能向上: +3-5% (Heavy時)
実装コスト: 6-8日
ROI: ⭐⭐⭐⭐⭐
Stretch Goal
メモリ削減: -4-6 MB (全pool統合)
性能向上: +5-10%
完全動的: ✅
ROI: 🌟🌟🌟🌟🌟
⚠️ リスク分析
Risk 1: 想定と実態の乖離
Phase 8再現:
Magazine想定4MB → 実測0.03MB
対策:
- Phase 1調査を徹底
- 実測データで判断
- 想定で実装しない
Risk 2: 性能劣化
懸念:
- Cache flush → Re-allocation増加
- Adaptive → 測定overhead
対策:
- 段階的実装
- Benchmark各段階
- 性能低下 > 5% → 撤退
Risk 3: 複雑度増加
懸念:
- State管理
- Adaptive logic
- デバッグ困難
対策:
- Simple Flush優先
- Adaptive はoptional
- Logging充実
✅ 結論
動的大作戦は Go!
理由:
- ✅ メモリ削減期待: -2-4 MB
- ✅ 性能向上可能性: +3-5%
- ✅ Phase 8手法適用可能
- ✅ ROI良好
- ✅ 本来の目標
推奨アプローチ
Step 1: 調査 (1-2日)
- 現状把握
- Overhead測定
- smaps解析
Step 2: Simple Flush (1-2日)
- Phase 7.7パターン
- 効果測定
- Go/No-Go判断
Step 3: Adaptive (Optional, 2-3日)
- Step 2効果次第
- 性能最適化
- 完全制覇
期待成果
Conservative:
Memory: -1-2 MB
Performance: ±0%
Target:
Memory: -2-4 MB
Performance: +3-5%
Combined with Phase 8.1:
Total gap: 6.0 → 2-4 MB
vs mimalloc: +24% → +8-16% 🎯
🏆 Production-grade完全達成!
次のアクション: Phase 1調査開始! 🔍