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>
12 KiB
hakmem 実装ロードマップ(ハイブリッド案)(2025-11-01)
戦略: ハイブリッドアプローチ
- ≤1KB (Tiny): 静的最適化(P0完了、学習不要)
- 8-32KB (Mid): mimalloc風 per-thread segment(MT性能最優先)
- ≥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/s(mimalloc の 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/s(mimalloc の 82%以上)
- ✅ 他のベンチマークへの影響なし
- ✅ 学習層(64KB以上)は無変更
リスク管理
- サイズ検索のオーバーヘッド → segment registry で解決
- メモリオーバーヘッド → 64KB chunk(mimalloc並み)
- スレッド数が多い場合 → 各スレッド独立、問題なし
詳細設計: 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 Pool(64KB以上)
実装: 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 と同等~上回る性能を達成
🎯 実装優先度まとめ
今週(最優先)
- ✅ ドキュメント更新(完了)
- 🔥 Phase 1: Mid Range MT最適化(始める)
- Day 1-2: 設計ドキュメント + 基本実装
- Day 3-4: 統合 + テスト
- Day 5-7: ベンチマーク + 最適化
来週
- Phase 2: ChatGPT Pro P1-P2(3-5日)
長期(1-2ヶ月)
- 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 設計ドキュメント作成 → 実装開始