Files
hakmem/archive/phase2/IMPLEMENTATION_ROADMAP.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

12 KiB
Raw Blame History

hakmem 実装ロードマップ(ハイブリッド案)(2025-11-01)

戦略: ハイブリッドアプローチ

  • ≤1KB (Tiny): 静的最適化P0完了、学習不要
  • 8-32KB (Mid): mimalloc風 per-thread segmentMT性能最優先
  • ≥64KB (Large): 学習ベースELO戦略が活きる

基準ドキュメント:

  • NEXT_STEP_ANALYSIS.md - ハイブリッド案の詳細分析
  • P0_SUCCESS_REPORT.md - P0実装成功レポート
  • docs/analysis/CHATGPT_PRO_ULTRATHINK_RESPONSE.md - ChatGPT Pro 推奨

📊 現在の性能状況P0実装後

ベンチマーク hakmem (hakx) mimalloc 差分 状況
Tiny Hot 32B 215 M ops/s 182 M ops/s +18% 勝利P0で改善
Random Mixed 22.5 M ops/s 25.1 M ops/s -10% ⚠️ 負け
mid_large_mt 46-47 M ops/s 122 M ops/s -62% 惨敗(最大の課題)

P0成果: Tiny Pool リフィルバッチ化で +5.16%

  • IPC: 4.71 → 5.35 (+13.6%)
  • L1キャッシュミス: -80%
  • 命令数/op: 100.1 → 101.8 (+1.7%だが実行効率向上)

Phase 0: Tiny Pool 最適化(完了)

実装内容

  • P0: 完全バッチ化ChatGPT Pro 推奨)
    • core/hakmem_tiny_refill_p0.inc.h 新規作成
    • sll_refill_batch_from_ss() 実装
    • ss_active_inc × 64 → ss_active_add × 1

成果

  • Tiny Hot: 202.55M → 213.00M (+5.16%)
  • IPC向上: 4.71 → 5.35 (+13.6%)
  • L1キャッシュミス削減: -80%

教訓

  • 3層アーキテクチャ失敗: ホットパス変更で -63%
  • P0成功: リフィルのみ最適化、ホットパス不変で +5.16%
  • 💡 ホットパスは触らない、スローパスだけ最適化

詳細: P0_SUCCESS_REPORT.md, 3LAYER_FAILURE_ANALYSIS.md


🎯 Phase 1: Mid Range MT最適化最優先、1週間

目標

  • mid_large_mt: 46M → 100-120M (+120-160%)
  • mimalloc 並みのMT性能達成
  • 学習層への影響: なし64KB以上は無変更

問題分析

現状の処理フロー:

8-32KB → L2 Pool (hakmem_pool.c)
         ↓
     ELO戦略選択オーバーヘッド
         ↓
     Global Poolロック競合
         ↓
     MT性能: 46M ops/smimalloc の 38%

mimalloc の処理フロー:

8-32KB → per-thread segment
         ↓
     TLSから直接取得ロックフリー
         ↓
     MT性能: 122M ops/s

根本原因: ロック競合 + 戦略選択オーバーヘッド

実装計画

1.1 新規ファイル作成

core/hakmem_mid_mt.h - per-thread segment 定義

#ifndef HAKMEM_MID_MT_H
#define HAKMEM_MID_MT_H

// Mid Range size classes (8KB, 16KB, 32KB)
#define MID_NUM_CLASSES 3
#define MID_CLASS_8KB   0
#define MID_CLASS_16KB  1
#define MID_CLASS_32KB  2

// per-thread segment (mimalloc風)
typedef struct MidThreadSegment {
    void* free_list;       // Free list head
    void* current;         // Current allocation pointer
    void* end;             // Segment end
    size_t size;           // Segment size (64KB chunk)
    uint32_t used_count;   // Used blocks in segment
    uint32_t capacity;     // Total capacity
} MidThreadSegment;

// TLS segments (one per size class)
extern __thread MidThreadSegment g_mid_segments[MID_NUM_CLASSES];

// API
void* mid_mt_alloc(size_t size);
void mid_mt_free(void* ptr, size_t size);

#endif

core/hakmem_mid_mt.c - 実装

#include "hakmem_mid_mt.h"
#include <sys/mman.h>

__thread MidThreadSegment g_mid_segments[MID_NUM_CLASSES] = {0};

// Segment size: 64KB chunk per class
#define SEGMENT_SIZE (64 * 1024)

static int size_to_mid_class(size_t size) {
    if (size <= 8192) return MID_CLASS_8KB;
    if (size <= 16384) return MID_CLASS_16KB;
    if (size <= 32768) return MID_CLASS_32KB;
    return -1;
}

static void* segment_alloc_new(MidThreadSegment* seg, size_t block_size) {
    // Allocate new 64KB segment
    void* mem = mmap(NULL, SEGMENT_SIZE,
                     PROT_READ | PROT_WRITE,
                     MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if (mem == MAP_FAILED) return NULL;

    seg->current = (char*)mem + block_size;
    seg->end = (char*)mem + SEGMENT_SIZE;
    seg->size = SEGMENT_SIZE;
    seg->capacity = SEGMENT_SIZE / block_size;
    seg->used_count = 1;

    return mem;
}

void* mid_mt_alloc(size_t size) {
    int class_idx = size_to_mid_class(size);
    if (class_idx < 0) return NULL;

    MidThreadSegment* seg = &g_mid_segments[class_idx];
    size_t block_size = (class_idx == 0) ? 8192 :
                        (class_idx == 1) ? 16384 : 32768;

    // Fast path: pop from free list
    if (seg->free_list) {
        void* p = seg->free_list;
        seg->free_list = *(void**)p;
        return p;
    }

    // Bump allocation from current segment
    void* current = seg->current;
    if (current && (char*)current + block_size <= (char*)seg->end) {
        seg->current = (char*)current + block_size;
        seg->used_count++;
        return current;
    }

    // Allocate new segment
    return segment_alloc_new(seg, block_size);
}

void mid_mt_free(void* ptr, size_t size) {
    if (!ptr) return;

    int class_idx = size_to_mid_class(size);
    if (class_idx < 0) return;

    MidThreadSegment* seg = &g_mid_segments[class_idx];

    // Push to free list
    *(void**)ptr = seg->free_list;
    seg->free_list = ptr;
    seg->used_count--;
}

1.2 メインルーティングの変更

core/hakmem.c - malloc/free にルーティング追加

#include "hakmem_mid_mt.h"

void* malloc(size_t size) {
    // ... recursion guard etc ...

    // Size-based routing
    if (size <= TINY_MAX_SIZE) {  // ≤1KB
        return hak_tiny_alloc(size);
    }

    if (size <= 32768) {  // 8-32KB: Mid Range MT
        return mid_mt_alloc(size);
    }

    // ≥64KB: Existing L2.5/Whale (学習ベース)
    return hak_alloc_at(size, HAK_CALLSITE());
}

void free(void* ptr) {
    if (!ptr) return;

    // ... recursion guard etc ...

    // Determine pool by size lookup
    size_t size = hak_usable_size(ptr);  // Need to implement

    if (size <= TINY_MAX_SIZE) {
        hak_tiny_free(ptr);
        return;
    }

    if (size <= 32768) {
        mid_mt_free(ptr, size);
        return;
    }

    // ≥64KB: Existing free path
    hak_free_at(ptr, 0, HAK_CALLSITE());
}

1.3 サイズ検索の実装

core/hakmem_mid_mt.c - segment registry

// Simple segment registry (for size lookup in free)
typedef struct {
    void* segment_base;
    size_t block_size;
} SegmentInfo;

#define MAX_SEGMENTS 1024
static SegmentInfo g_segment_registry[MAX_SEGMENTS];
static int g_segment_count = 0;

static void register_segment(void* base, size_t block_size) {
    if (g_segment_count < MAX_SEGMENTS) {
        g_segment_registry[g_segment_count].segment_base = base;
        g_segment_registry[g_segment_count].block_size = block_size;
        g_segment_count++;
    }
}

static size_t lookup_segment_size(void* ptr) {
    for (int i = 0; i < g_segment_count; i++) {
        void* base = g_segment_registry[i].segment_base;
        if (ptr >= base && ptr < (char*)base + SEGMENT_SIZE) {
            return g_segment_registry[i].block_size;
        }
    }
    return 0;  // Not found
}

作業工数

  • Day 1-2: ファイル作成、基本実装
  • Day 3-4: ルーティング統合、テスト
  • Day 5: ベンチマーク、チューニング
  • Day 6-7: バグ修正、最適化

成功基準

  • mid_large_mt: 100+ M ops/smimalloc の 82%以上)
  • 他のベンチマークへの影響なし
  • 学習層64KB以上は無変更

リスク管理

  • サイズ検索のオーバーヘッド → segment registry で解決
  • メモリオーバーヘッド → 64KB chunkmimalloc並み
  • スレッド数が多い場合 → 各スレッド独立、問題なし

詳細設計: docs/design/MID_RANGE_MT_DESIGN.md(次に作成)


🔧 Phase 2: ChatGPT Pro P1-P2中優先、3-5日

目標

  • Random Mixed: 22.5M → 24M (+7%)
  • Tiny Hot: 215M → 220M (+2%)

実装項目

2.1 P1: Quick補充の粒度可変化

現状: quick_refill_from_sll は最大2個

if (room > 2) room = 2;  // 固定

改善: g_frontend_fill_target による動的調整

int target = g_frontend_fill_target[class_idx];
if (room > target) room = target;

期待効果: +1-2%

2.2 P2: Remote Freeしきい値最適化

現状: 全クラス共通の g_remote_drain_thresh

改善: クラス別しきい値テーブル

// Hot classes (0-2): 高しきい値(バースト吸収)
static const int g_remote_thresh[TINY_NUM_CLASSES] = {
    64,  // class 0: 8B
    64,  // class 1: 16B
    64,  // class 2: 32B
    32,  // class 3: 64B
    16,  // class 4+: 即時性優先
    // ...
};

期待効果: MT性能 +2-3%

作業工数

  • Day 1-2: P1実装、テスト
  • Day 3: P2実装、テスト
  • Day 4-5: ベンチマーク、チューニング

📈 Phase 3: Long-term Improvements長期、1-2ヶ月

ChatGPT Pro P3: Bundle ノード

対象: 64KB以上の Large Pool

実装: Transfer Cache方式tcmalloc風

// Bundle node: 32/64個を1ードに
typedef struct BundleNode {
    void* items[64];
    int count;
    struct BundleNode* next;
} BundleNode;

期待効果: MT性能 +5-10%CAS回数削減

ChatGPT Pro P5: UCB1自動調整

対象: パラメータ自動チューニング

実装: 既存 hakmem_ucb1.c を活用

  • Frontend fill target
  • Quick rush size
  • Magazine capacity

期待効果: +3-5%(長期的にワークロード適応)

ChatGPT Pro P6: NUMA/CPUシャーディング

対象: Large Pool64KB以上

実装: NUMA node単位で Pool 分割

// NUMA-aware pool
int node = numa_node_of_cpu(cpu);
LargePool* pool = &g_large_pools[node];

期待効果: MT性能 +10-20%(ロック競合削減)


📊 最終目標Phase 1-3完了後

ベンチマーク 現状 Phase 1後 Phase 2後 Phase 3後
Tiny Hot 215 M 215 M 220 M 225 M
Random Mixed 22.5 M 23 M 24 M 25 M
mid_large_mt 46 M 110 M 115 M 130 M

総合評価: mimalloc と同等~上回る性能を達成


🎯 実装優先度まとめ

今週(最優先)

  1. ドキュメント更新(完了)
  2. 🔥 Phase 1: Mid Range MT最適化(始める)
    • Day 1-2: 設計ドキュメント + 基本実装
    • Day 3-4: 統合 + テスト
    • Day 5-7: ベンチマーク + 最適化

来週

  1. Phase 2: ChatGPT Pro P1-P23-5日

長期1-2ヶ月

  1. Phase 3: P3, P5, P6

🤔 設計原則(ハイブリッド案)

1. 領域別の最適化戦略

≤1KB (Tiny)   → 静的最適化(学習不要)
                 P0完了、これ以上の改善は限定的

8-32KB (Mid)  → MT性能最優先学習不要
                 mimalloc風 per-thread segment

≥64KB (Large) → 学習ベースELO戦略
                 ワークロード適応が効果的

2. 学習層の役割

  • Tiny: 学習しないP0で最適化完了
  • Mid: 学習しないmimalloc風に移行
  • Large: 学習が主役ELO戦略選択

→ 学習層のオーバーヘッドを最小化、効果的な領域に集中

3. トレードオフ

mimalloc 真似(全面):

  • MT性能最高
  • 学習層が死ぬ
  • hakmem の差別化ポイント喪失

ChatGPT Pro全面:

  • 学習層が活きる
  • MT性能が届かない

ハイブリッド(採用):

  • MT性能最高8-32KB
  • 学習層保持≥64KB
  • 段階的実装
  • 両者の良いとこ取り

📚 参考資料

  • NEXT_STEP_ANALYSIS.md - ハイブリッド案の詳細分析
  • P0_SUCCESS_REPORT.md - P0実装成功レポート
  • 3LAYER_FAILURE_ANALYSIS.md - 3層アーキテクチャ失敗分析
  • docs/analysis/CHATGPT_PRO_ULTRATHINK_RESPONSE.md - ChatGPT Pro 推奨
  • docs/design/MID_RANGE_MT_DESIGN.md - Mid Range MT設計次に作成

最終更新: 2025-11-01 ステータス: Phase 0完了P0、Phase 1準備中Mid Range MT 次のアクション: Mid Range MT 設計ドキュメント作成 → 実装開始