Files
hakmem/docs/status/PHASE_6.25_MIMALLOC_STRATEGY_2025_10_24.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

21 KiB
Raw Blame History

mimalloc 制覇計画

日付: 2025-10-24 ステータス: 戦略策定完了 目標: mimalloc に迫る、一部で超える


Executive Summary

Phase 6.24 で Tiny Pool の SuperSlab 基盤が完成しました275.10 M ops/sec @ bench_tiny_mt 4T。次は mimalloc を倒すための全体戦略を立てます。

現状の達成率vs mimalloc

Pool Benchmark 1T 達成率 4T 達成率 ボトルネック
Tiny (8-64B) larson 3s 62% 70% TLS/Magazine 最適化不足
Mid (2-32KB) larson 3s 25% 37% Refill コスト、TLS Ring 不足
Large (64KB-1MB) larson 3s (測定不可) (測定不可) Large ベンチ未完走

優先順位

Phase 6.25-6.27: Mid Pool 集中最適化(最大のボトルネック) Phase 6.28-6.29: Tiny Pool 完成Magazine 統合) Phase 6.30: Large Pool 最適化(余裕があれば)


1. 現状分析

1.1 Tiny Pool (8-1KB)

Performance Data

Benchmark Threads hakmem mimalloc 達成率 絶対差
larson 3s 1T 21.0 M/s 33.8 M/s 62% -12.8 M/s
larson 3s 4T 53.5 M/s 76.5 M/s 70% -23.0 M/s
bench_tiny_mt 4T 275.10 M/s (未測定) (不明) -

: bench_tiny_mt は 16B 固定、larson は 8-64B 混在

ボトルネック分析

  1. Magazine と SuperSlab の二重構造

    • MagazineTLS cacheと SuperSlab が並行運用
    • 両方のオーバーヘッドが累積
    • mimalloc は SuperSlab 直結で無駄なし
  2. 16B 以外のサイズクラス最適化不足

    • bench_tiny_mt16B のみ): 275 M/s良好
    • larson8-64B 混在): 53.5 M/s低い
    • 8B, 32B, 64B クラスが遅い可能性
  3. TLS アクセスコスト

    • Phase 6.24 で 3 TLS reads → 1 TLS read に削減済み
    • さらなる最適化は困難

改善余地

  • Impact: Medium70% → 85-90% 目標)
  • Effort: Medium-HighMagazine 統合は大手術)
  • 優先度: P2Mid Pool の後)

1.2 Mid Pool (2-52KB)

Performance Data

Benchmark Threads hakmem mimalloc 達成率 絶対差
larson 3s 1T 3.93 M/s 15.5 M/s 25% -11.6 M/s
larson 3s 4T 10.0 M/s 26.9 M/s 37% -16.9 M/s

Phase 6.20 比較:

  • 1T: 4.3 M/s → 3.93 M/s (-8.6%, CAP 削減の影響)
  • 4T: 9.6 M/s → 10.0 M/s (+4.2%, Lock 競合削減)

ボトルネック分析

  1. Refill 処理の重さ 🔴 Critical

    • 1 ページ refill = mmap + metadata 初期化 + freelist 構築
    • TLS Ring miss 時に毎回実行される
    • mimalloc は Segment-Aligned で refill コストが低い
  2. TLS Ring Buffer が小さすぎる

    • 現状: POOL_TLS_RING_CAP=1616 ページキャッシュ)
    • 2-52KB range で 7 classes × 16 = 112 pages 合計
    • larson は allocation pattern が複雑 → Ring miss 頻発
  3. Lock 競合

    • Phase 6.21 で CAP 削減により 4T が +4.2% 改善
    • さらなる Lock-free 化の余地あり
  4. Headerless allocation の恩恵が薄い

    • Phase 6.22+ で Headerless 実装済み
    • しかし性能向上は限定的(他のボトルネックが大きい)

改善余地

  • Impact: Very High25% → 60-70% 目標)
  • Effort: Low-MediumTLS Ring 拡大、Refill 最適化)
  • 優先度: P1(最優先)

1.3 Large Pool (64KB-2MB)

Performance Data

Benchmark Threads hakmem mimalloc 達成率
larson 3s 1T 0.94 M/s timeout (不明)
larson 3s 4T 1.27 M/s (未測定) (不明)

Phase 6.18-6.20 の改善:

  • L2.5 Pool の RUN_FACTOR, TC_SPILL, HDR_LIGHT チューニング完了
  • Remote free queue 実装済み
  • P1/P2 プロファイル確立

ボトルネック分析

  1. ベンチマーク測定不可

    • mimalloc が Large でタイムアウト(環境問題?)
    • 絶対的な性能比較ができない
  2. Allocation size が大きい

    • 64KB-2MB は mmap コストが支配的
    • Pool の恩恵が Mid より小さい
  3. ELO system のオーバーヘッド

    • 12 strategies の選択コスト
    • 大きな allocation には不要かも

改善余地

  • Impact: Medium測定不可のため不明
  • Effort: Medium
  • 優先度: P3Mid/Tiny の後)

2. mimalloc との性能差(詳細)

2.1 Allocation Size 別比較

Size Type hakmem 1T mimalloc 1T Gap hakmem 4T mimalloc 4T Gap
16B Tiny 21.0 M/s 33.8 M/s -38% 53.5 M/s 76.5 M/s -30%
4KB Mid 3.93 M/s 15.5 M/s -75% 10.0 M/s 26.9 M/s -63%
16KB Mid (含む) (含む) - (含む) (含む) -
32KB Mid (含む) (含む) - (含む) (含む) -
64KB Large 0.94 M/s (不明) - 1.27 M/s (不明) -
256KB Large (含む) (不明) - (含む) (不明) -
1MB Large (含む) (不明) - (含む) (不明) -

最大の問題: Mid 4KB-32KB range が 63-75% 遅い

2.2 Multi-threaded Scalability

Pool 1T → 4T Scaling (hakmem) 1T → 4T Scaling (mimalloc) 分析
Tiny 21.0 → 53.5 (2.5x) 33.8 → 76.5 (2.3x) hakmem の方が scalability 良好
Mid 3.93 → 10.0 (2.5x) 15.5 → 26.9 (1.7x) hakmem の方が scalability 良好

発見: hakmem は multi-threaded scalability が良いTLS Ring の効果) 戦略: 1T を改善すれば 4T も自動的に向上


3. 優先順位マトリクス

Impact vs Effort マトリクス

最適化 Pool Impact Effort Priority Phase 期待効果
TLS Ring 拡張 Mid Very High Low P1 6.25 +10-15%
Refill Batching Mid High Low P1 6.25 +5-10%
Headerless 最適化 Mid Medium Low P1 6.26 +3-5%
Lock-free Refill Mid High Medium P2 6.26 +5-10%
Tiny Magazine 統合 Tiny High High P2 6.28 +10-15%
Tiny 全サイズクラス最適化 Tiny Medium Medium P2 6.28 +5-8%
SuperSlab Long-term fix Tiny Medium Medium P2 6.29 +3-5%
Large L2.5 Pool 最適化 Large Low Medium P3 6.30 +5-10%
ELO System 簡略化 Large Low Low P3 6.30 +2-3%

優先順位の理由

  1. Mid Pool が最大のボトルネック

    • mimalloc の 25-37% しか出ていない(最大の Gap
    • 実装が簡単な最適化が残っているTLS Ring 拡張、Refill Batching
    • 短期間で大きな効果が期待できる
  2. Tiny Pool は既に良好

    • bench_tiny_mt で 275 M/s 達成(十分速い)
    • larson では 70% 達成(悪くない)
    • Magazine 統合は大手術なので後回し
  3. Large Pool は測定不可

    • mimalloc とのベンチマーク比較ができない
    • 優先度を下げて Mid/Tiny に集中

4. Phase 6.25-6.30 ロードマップ

Phase 6.25: Mid Pool 緊急最適化TLS Ring + Refill Batching

目標: Mid 1T/4T を +20-30% 改善3.93 → 4.7 M/s @ 1T, 10.0 → 13.0 M/s @ 4T

実装内容:

  1. TLS Ring Buffer 拡張 (1-2時間)

    // hakmem_pool.h:85
    #define POOL_TLS_RING_CAP 32  // 16 → 32 (2倍)
    
    • 期待効果: +8-12%
    • 理由: Ring miss 頻度削減 → Refill 回数削減
  2. Refill Batching (2-3時間)

    // refill_freelist() 改善
    // 1ページではなく 2-4 ページを一度に確保
    void refill_freelist_batch(int class_idx, int batch_size) {
        for (int i = 0; i < batch_size; i++) {
            void* page = mmap(...);  // 1回の syscall で複数ページ
            initialize_page(page, class_idx);
        }
    }
    
    • 期待効果: +5-8%
    • 理由: syscall 頻度削減、mmap オーバーヘッド削減
  3. Prefault Pages (1時間)

    // mmap 直後に touch してページフォールトを回避
    void prefault_page(void* page, size_t size) {
        for (size_t i = 0; i < size; i += 4096) {
            ((char*)page)[i] = 0;  // Touch each page
        }
    }
    
    • 期待効果: +2-3%
    • 理由: TLB miss 削減、first-touch latency 削減

実装時間: ~6時間 優先度: High リスク: Low既存機能の拡張のみ

Phase 6.26: Mid Pool 構造最適化Headerless + Lock-free

目標: Mid 1T/4T をさらに +15-20% 改善4.7 → 5.5 M/s @ 1T, 13.0 → 15.6 M/s @ 4T

実装内容:

  1. Headerless Allocation の完全最適化 (3-4時間)

    • 現状の HDR_LIGHT=2 の性能プロファイリング
    • ページ記述子アクセスの高速化
    • Inline 化とキャッシュ効率改善

    期待効果: +3-5%

  2. Lock-free Refill Path (4-6時間)

    // CAS-based page allocation from global pool
    void* refill_lockfree(int class_idx) {
        Page* page;
        do {
            page = g_pool.free_pages[class_idx];
            if (!page) return refill_slow_path(class_idx);
        } while (!__atomic_compare_exchange_n(&g_pool.free_pages[class_idx],
                                              &page, page->next, ...));
        return page;
    }
    
    • 期待効果: +8-12%
    • 理由: Lock 競合削減(特に 4T
  3. Active Page 2枚化 (2-3時間)

    • TLS に 2 枚の Active Page をキャッシュ
    • Bitmap 走査の頻度削減
    • 期待効果: +2-3%

実装時間: ~12時間 優先度: High リスク: MediumLock-free は慎重に実装)

Phase 6.27: Mid Pool 仕上げLearner 統合 + 動的調整)

目標: Mid 1T/4T で mimalloc の 60-70% 達成5.5 → 9.3 M/s @ 1T, 15.6 → 18.8 M/s @ 4T

実装内容:

  1. Learner による CAP 動的調整 (2-3時間)

    • HAKMEM_LEARN=1 での最適 CAP 自動設定
    • Phase 6.21 で CAP 削減により 1T が -8.6% 低下
    • Learner で workload に応じて CAP を調整

    期待効果: +3-5% (1T)

  2. Background Refill (4-5時間)

    • 閾値(例: Ring 50% 以下)で非同期 refill 開始
    • ホットパスへの影響なし
    • 期待効果: +2-4%
  3. W_MAX_MID 緩和実験 (1時間)

    pol->w_max_mid = 1.60f;  // 1.40 → 1.60
    
    • トレードオフ: 内部断片化 ↑、ヒット率 ↑
    • A/B テストで効果確認

    期待効果: +2-5%

実装時間: ~8時間 優先度: Medium リスク: Low

Phase 6.28: Tiny Pool 完成Magazine 統合)

目標: Tiny 1T/4T で mimalloc の 80-90% 達成21.0 → 27-30 M/s @ 1T, 53.5 → 61-69 M/s @ 4T

実装内容:

  1. Magazine と SuperSlab の統合 (8-12時間)

    • Magazine を削除、SuperSlab 直結に統一
    • mimalloc スタイルの allocation path
    • TLS で SuperSlab の active slab をキャッシュ

    実装例:

    void* hak_tiny_alloc(size_t size) {
        int class_idx = SIZE_TO_CLASS[size >> 3];
        TinyTLSSlab* tls = &g_tls_slabs[class_idx];
    
        // Fast path: Direct from cached slab metadata
        if (tls->meta && tls->meta->freelist) {
            void* block = tls->meta->freelist;
            tls->meta->freelist = *(void**)block;
            tls->meta->used++;
            return block;
        }
    
        // Slow path: Refill from SuperSlab
        return refill_from_superslab(class_idx);
    }
    

    期待効果: +10-15% 理由: 二重構造の解消、TLS アクセス削減

  2. 全サイズクラス8B, 32B, 64B最適化 (4-6時間)

    • 現状 16B に最適化が集中
    • 8B, 32B, 64B の freelist 構築を最適化
    • Lazy initialization を全クラスに適用

    期待効果: +5-8%

実装時間: ~16時間 優先度: Medium リスク: High既存の Magazine を削除する大手術)

Phase 6.29: Tiny Pool 仕上げLong-term fix

目標: Tiny 4T で mimalloc を超える53.5 → 80+ M/s @ 4T

実装内容:

  1. Remote Free Queue の最適化 (3-4時間)

    • Per-thread remote queue の実装
    • Lock-free queueMichael-Scott queue
    • Cross-thread free の高速化

    期待効果: +3-5% (4T)

  2. SuperSlab 再利用の改善 (2-3時間)

    • Global pool から empty SuperSlab を取得
    • munmap の遅延化
    • 2MB mmap コストの削減

    期待効果: +2-3%

  3. Compiler Flag 最適化 (1時間)

    CFLAGS += -march=native -mtune=native
    CFLAGS += -flto  # Link-Time Optimization
    
    • 期待効果: +2-4%

実装時間: ~7時間 優先度: Medium-Low リスク: Low

Phase 6.30: Large Pool 最適化(余裕があれば)

目標: Large Pool の性能把握と最適化

実装内容:

  1. Large ベンチマーク環境修正 (2時間)

    • mimalloc が timeout する問題を解決
    • 別のベンチマークを使用(例: cache-scratch
    • 目標: mimalloc との比較可能にする
  2. L2.5 Pool の Capacity 調整 (2時間)

    • 現状の CAP を分析
    • Learner での最適化
    • 期待効果: +5-10%
  3. ELO System 簡略化 (3-4時間)

    • 12 strategies → 6 strategies に削減
    • 選択コストの削減
    • 期待効果: +2-3%

実装時間: ~8時間 優先度: Low リスク: Low


5. Quick wins即実装可能

以下の最適化は 1-2時間以内に実装でき、リスクが低く、効果が明確です。Phase 6.25 の前に実施推奨。

1. TLS Ring Buffer 拡張30分

実装:

// hakmem_pool.h:85
#define POOL_TLS_RING_CAP 32  // 16 → 32

テスト:

make clean && make libhakmem.so
RUNTIME=3 THREADS=1,4 ./scripts/run_bench_suite.sh

期待効果: Mid 1T/4T で +8-12% リスク: 極低メモリ増加のみ、16 × 64KB × 7 classes = 7 MB 増加)

2. Compiler Flags 最適化15分

実装:

# Makefile:7-9
CFLAGS = -O2 -g -Wall -Wextra -pthread -fPIC
CFLAGS += -march=native -mtune=native  # NEW!
CFLAGS += -flto                        # NEW! (Link-Time Optimization)

テスト:

make clean && make libhakmem.so
RUNTIME=3 THREADS=1,4 ./scripts/run_bench_suite.sh

期待効果: 全体で +2-4% リスク: 極低GCC が最適化を自動実行)

3. W_MAX_MID 緩和実験10分

実装:

// hakmem_policy.c:81
pol->w_max_mid = 1.60f;  // 1.40 → 1.60

テスト:

make clean && make libhakmem.so
RUNTIME=3 THREADS=1,4 ./scripts/run_bench_suite.sh

期待効果: Mid 1T/4T で +2-5%(内部断片化は増加) リスク: 低(メモリ効率のトレードオフ)

4. Prefault Pages30分

実装:

// hakmem_pool.c: refill_freelist() 内
void* page = mmap(...);
if (page != MAP_FAILED) {
    // Prefault: Touch each 4KB page to avoid TLB miss
    for (size_t i = 0; i < POOL_PAGE_SIZE; i += 4096) {
        ((volatile char*)page)[i] = 0;
    }
    // ... existing initialization
}

期待効果: Mid 1T/4T で +2-3% リスク: 極低(初回アクセス latency のみ増加、総 throughput は向上)

合計実装時間: ~1.5時間

合計期待効果: +14-24% (Mid Pool)

合計リスク: 極低


6. 最終目標

Phase 6.30 完了時の目標値

Pool Metric Phase 6.24 Phase 6.30 目標 mimalloc 達成率 目標
Tiny 1T 21.0 M/s 27-30 M/s 33.8 M/s 80-89%
Tiny 4T 53.5 M/s 61-69 M/s 76.5 M/s 80-90%
Mid 1T 3.93 M/s 9.3-11.6 M/s 15.5 M/s 60-75%
Mid 4T 10.0 M/s 16.1-20.1 M/s 26.9 M/s 60-75%
Large 1T 0.94 M/s 1.0-1.2 M/s (不明) 70%+
Large 4T 1.27 M/s 1.5-1.8 M/s (不明) 70%+

Overall 目標

  • Tiny Pool: mimalloc 並み or 超える(特に 4T
  • Mid Pool: mimalloc の 60-75% 達成(現状 25-37% から大幅改善)
  • Large Pool: mimalloc の 70%+ 達成(測定可能になれば)
  • Overall: mimalloc に迫る、一部Tiny 4Tで超える

マイルストーン

Phase 完了日目標 Mid 1T 達成率 Mid 4T 達成率 Status
6.24 2025-10-24 25% 37% 完了
6.25 2025-10-25 35-40% 48-52% 🔜
6.26 2025-10-26 45-50% 58-62% 予定
6.27 2025-10-27 55-60% 65-70% 予定
6.28 2025-10-28 - - 予定Tiny
6.29 2025-10-29 - - 予定Tiny
6.30 2025-10-30 60-75% 60-75% 最終目標

7. 実装の進め方

Step 1: Quick wins今日中

  1. TLS Ring Buffer 拡張30分
  2. Compiler Flags 最適化15分
  3. W_MAX_MID 緩和実験10分
  4. Prefault Pages30分
  5. ベンチマーク測定30分

合計: ~2時間

Step 2: Phase 6.25 本体(明日)

  1. Refill Batching 実装2-3時間
  2. ベンチマーク測定 & 結果分析1時間
  3. ドキュメント更新30分

合計: ~4時間

Step 3: Phase 6.26-6.301週間

  • 毎日 1 Phase ずつ実装
  • 各 Phase 終了時に必ずベンチマーク測定
  • 性能低下があれば即座に rollback

測定基準

必須ベンチマーク(各 Phase 終了時):

# 1. larson suite (3秒、1T/4T)
RUNTIME=3 THREADS=1,4 ./scripts/run_bench_suite.sh

# 2. bench_tiny_mt (Tiny Pool 専用)
./bench_tiny_mt

# 3. larson Mid 詳細10秒、4T
LD_PRELOAD=./libhakmem.so mimalloc-bench/bench/larson/larson 10 2048 32768 10000 1 12345 4

記録すべき項目:

  • Throughput (ops/sec)
  • vs mimalloc 達成率(%
  • vs 前 Phase 改善率(%
  • RSS (KB)

8. リスク管理

High-Risk 項目

  1. Tiny Magazine 統合Phase 6.28

    • 既存の Magazine を削除する大手術
    • Backward compatibility が失われる可能性
    • 対策: Phase 6.27 まで Magazine を残し、SuperSlab が完全に動作することを確認してから統合
  2. Lock-free RefillPhase 6.26

    • CAS-based の実装は race condition のリスク
    • 対策: 徹底的なテスト、ThreadSanitizer で検証

Medium-Risk 項目

  1. Refill BatchingPhase 6.25

    • Batch size が大きすぎるとメモリ無駄
    • 対策: 2-4 ページから開始、A/B テストで最適値を探る
  2. W_MAX 緩和Phase 6.25, 6.27

    • 内部断片化が増加
    • 対策: RSS を測定し、許容範囲内(+10% 以下)に収める

Low-Risk 項目

  • TLS Ring Buffer 拡張
  • Compiler Flags 最適化
  • Prefault Pages
  • Learner 統合

9. 成功基準

Must Have必須

  • Mid Pool 1T/4T で +100% 改善3.93 → 7.86+ M/s @ 1T, 10.0 → 20.0+ M/s @ 4T
  • Tiny Pool 1T/4T で +20% 改善21.0 → 25.2+ M/s @ 1T, 53.5 → 64.2+ M/s @ 4T
  • 性能低下なし(各 Phase で前回比 -5% 以下)
  • ビルド成功(全 Phase

Should Have推奨

  • Mid Pool で mimalloc の 60%+ 達成
  • Tiny Pool で mimalloc の 80%+ 達成
  • メモリフットプリント +20% 以下Phase 6.21 比)

Nice to Haveあれば良い

  • Tiny 4T で mimalloc を超える76.5 M/s 以上)
  • Mid 4T で mimalloc の 70%+ 達成
  • Large Pool の mimalloc 比較測定完了

10. まとめ

現状

  • Tiny Pool: 70% 達成(良好)
  • Mid Pool: 37% 達成(最大のボトルネック
  • Large Pool: 測定不可

戦略

  1. Phase 6.25-6.27: Mid Pool 集中最適化Quick wins + Refill Batching + Lock-free
  2. Phase 6.28-6.29: Tiny Pool 完成Magazine 統合 + 全サイズクラス最適化)
  3. Phase 6.30: Large Pool 最適化(余裕があれば)

最終目標

  • Mid Pool: mimalloc の 60-75% 達成(現状 25-37% から 2-3倍改善
  • Tiny Pool: mimalloc の 80-90% 達成(現状 62-70% から 1.3倍改善)
  • Overall: mimalloc に迫る、一部で超える

次のアクション

今日中Phase 6.25 準備):

  1. TLS Ring Buffer 拡張30分
  2. Compiler Flags 最適化15分
  3. W_MAX_MID 緩和実験10分
  4. Prefault Pages30分
  5. ベンチマーク測定30分

明日Phase 6.25 本体):

  1. Refill Batching 実装2-3時間
  2. ベンチマーク測定 & 結果分析1時間

mimalloc、倒すぞー 🔥🔥🔥


作成日: 2025-10-24 13:00 JST ステータス: 戦略策定完了 次のフェーズ: Phase 6.25 (Mid Pool 緊急最適化)