# HAKMEM Tiny リファクタリング - 統合計画 ## 📋 Week 1.4: 統合戦略 ### 🎯 目標 新しい箱(Box 1, 5, 6)を既存コードに統合し、Feature flag で新旧を切り替え可能にする。 ### 🔧 Feature Flag 設計 #### Option 1: Phase 6 拡張(推奨)⭐ 既存の Phase 6 メカニズムを拡張する方法: ```c // Phase 6-1.7: Box Theory Refactoring (NEW) // - Enable: -DHAKMEM_TINY_PHASE6_BOX_REFACTOR=1 // - Speed: 58-65 M ops/sec (expected, +10-25%) // - Method: Box 1 (Atomic) + Box 5 (Alloc Fast) + Box 6 (Free Fast) // - Benefit: Clear boundaries, 3-4 instruction fast path // - Files: tiny_atomic.h, tiny_alloc_fast.inc.h, tiny_free_fast.inc.h ``` **利点**: - 既存の Phase 6 パターンと一貫性がある - 相互排他チェックが自動(#error ディレクティブ) - ユーザーが理解しやすい(Phase 6-1.5, 6-1.6, 6-1.7) **実装**: ```c #if defined(HAKMEM_TINY_PHASE6_METADATA) && defined(HAKMEM_TINY_PHASE6_ULTRA_SIMPLE) #error "Cannot enable both PHASE6_METADATA and PHASE6_ULTRA_SIMPLE" #endif // NEW: Box Refactor check #ifdef HAKMEM_TINY_PHASE6_BOX_REFACTOR #if defined(HAKMEM_TINY_PHASE6_METADATA) || defined(HAKMEM_TINY_PHASE6_ULTRA_SIMPLE) #error "Cannot enable PHASE6_BOX_REFACTOR with other Phase 6 options" #endif // Include new boxes #include "tiny_atomic.h" #include "tiny_alloc_fast.inc.h" #include "tiny_free_fast.inc.h" // Override alloc/free entry points #define hak_tiny_alloc(size) tiny_alloc_fast(size) #define hak_tiny_free(ptr) tiny_free_fast(ptr) #endif ``` #### Option 2: 独立 Flag(代替案) 新しい独立した flag を作る方法: ```c // Enable new box-based fast path // Usage: make CFLAGS="-DHAKMEM_TINY_USE_FAST_BOXES=1" #ifdef HAKMEM_TINY_USE_FAST_BOXES #include "tiny_atomic.h" #include "tiny_alloc_fast.inc.h" #include "tiny_free_fast.inc.h" #define hak_tiny_alloc(size) tiny_alloc_fast(size) #define hak_tiny_free(ptr) tiny_free_fast(ptr) #endif ``` **利点**: - シンプル - Phase 6 とは独立 **欠点**: - Phase 6 との相互排他チェックが必要 - 一貫性がやや低い ### 📝 統合ステップ(推奨: Option 1) #### Step 1: Feature Flag 追加(hakmem_tiny.c) ```c // File: core/hakmem_tiny.c // Location: Around line 1489 (after Phase 6 definitions) #if defined(HAKMEM_TINY_PHASE6_METADATA) && defined(HAKMEM_TINY_PHASE6_ULTRA_SIMPLE) #error "Cannot enable both PHASE6_METADATA and PHASE6_ULTRA_SIMPLE" #endif // NEW: Phase 6-1.7 - Box Theory Refactoring #ifdef HAKMEM_TINY_PHASE6_BOX_REFACTOR #if defined(HAKMEM_TINY_PHASE6_METADATA) || defined(HAKMEM_TINY_PHASE6_ULTRA_SIMPLE) #error "Cannot enable PHASE6_BOX_REFACTOR with other Phase 6 options" #endif // Box 1: Atomic Operations (Layer 0) #include "tiny_atomic.h" // Box 5: Allocation Fast Path (Layer 1) #include "tiny_alloc_fast.inc.h" // Box 6: Free Fast Path (Layer 2) #include "tiny_free_fast.inc.h" // Override entry points void* hak_tiny_alloc_box_refactor(size_t size) { return tiny_alloc_fast(size); } void hak_tiny_free_box_refactor(void* ptr) { tiny_free_fast(ptr); } // Export as default when enabled #define hak_tiny_alloc_wrapper(class_idx) hak_tiny_alloc_box_refactor(g_tiny_class_sizes[class_idx]) // Note: Free path needs different approach (see Step 2) #elif defined(HAKMEM_TINY_PHASE6_ULTRA_SIMPLE) // Phase 6-1.5: Alignment guessing (legacy) #include "hakmem_tiny_ultra_simple.inc" #elif defined(HAKMEM_TINY_PHASE6_METADATA) // Phase 6-1.6: Metadata header (recommended) #include "hakmem_tiny_metadata.inc" #endif ``` #### Step 2: Update hakmem.c Entry Points ```c // File: core/hakmem.c // Location: Around line 680 (hak_malloc implementation) void* hak_malloc(size_t size) { if (__builtin_expect(size == 0, 0)) return NULL; if (__builtin_expect(size <= 1024, 1)) { #ifdef HAKMEM_TINY_PHASE6_BOX_REFACTOR // Box Refactor: Direct call to Box 5 void* ptr = tiny_alloc_fast(size); if (ptr) return ptr; // Fall through to backend on OOM #elif defined(HAKMEM_TINY_PHASE6_ULTRA_SIMPLE) // Ultra Simple path void* ptr = hak_tiny_alloc_ultra_simple(size); if (ptr) return ptr; #else // Default Tiny path void* tiny_ptr = hak_tiny_alloc(size); if (tiny_ptr) return tiny_ptr; #endif } // Mid/Large/Whale fallback return hak_alloc_large_or_mid(size); } void hak_free(void* ptr) { if (__builtin_expect(!ptr, 0)) return; #ifdef HAKMEM_TINY_PHASE6_BOX_REFACTOR // Box Refactor: Direct call to Box 6 tiny_free_fast(ptr); return; #elif defined(HAKMEM_TINY_PHASE6_ULTRA_SIMPLE) // Ultra Simple path hak_tiny_free_ultra_simple(ptr); return; #else // Default path (with mid_lookup, etc.) hak_free_at(ptr, 0, 0); #endif } ``` #### Step 3: Makefile Update ```makefile # File: Makefile # Add new Phase 6 option # Phase 6-1.7: Box Theory Refactoring box-refactor: $(MAKE) clean $(MAKE) CFLAGS="$(CFLAGS) -DHAKMEM_TINY_PHASE6_BOX_REFACTOR=1" all @echo "Built with Box Refactor (Phase 6-1.7)" # Convenience target test-box-refactor: box-refactor ./larson_hakmem 10 8 128 1024 1 12345 4 ``` ### 🧪 テスト計画 #### Phase 1: コンパイル確認 ```bash # 1. Box Refactor のみ有効化 make CFLAGS="-DHAKMEM_TINY_PHASE6_BOX_REFACTOR=1" larson_hakmem # 2. 他の Phase 6 オプションと排他チェック make CFLAGS="-DHAKMEM_TINY_PHASE6_BOX_REFACTOR=1 -DHAKMEM_TINY_PHASE6_ULTRA_SIMPLE=1" larson_hakmem # Expected: Compile error (mutual exclusion) ``` #### Phase 2: 動作確認 ```bash # 1. 基本動作テスト make CFLAGS="-DHAKMEM_TINY_PHASE6_BOX_REFACTOR=1" larson_hakmem ./larson_hakmem 2 8 128 1024 1 12345 1 # Expected: No crash, basic allocation/free works # 2. マルチスレッドテスト ./larson_hakmem 10 8 128 1024 1 12345 4 # Expected: No crash, no A213 errors # 3. Guard mode テスト HAKMEM_TINY_DEBUG_REMOTE_GUARD=1 HAKMEM_SAFE_FREE=1 \ ./larson_hakmem 5 8 128 1024 1 12345 4 # Expected: No remote_invalid errors ``` #### Phase 3: パフォーマンス測定 ```bash # Baseline (現状) make clean && make larson_hakmem ./larson_hakmem 10 8 128 1024 1 12345 4 > baseline.txt grep "Throughput" baseline.txt # Expected: ~52 M ops/sec (or current value) # Box Refactor (新) make CFLAGS="-DHAKMEM_TINY_PHASE6_BOX_REFACTOR=1" larson_hakmem ./larson_hakmem 10 8 128 1024 1 12345 4 > box_refactor.txt grep "Throughput" box_refactor.txt # Target: 58-65 M ops/sec (+10-25%) ``` ### 📊 成功条件 | 項目 | 条件 | 検証方法 | |------|------|---------| | ✅ コンパイル成功 | エラーなし | `make CFLAGS="-DHAKMEM_TINY_PHASE6_BOX_REFACTOR=1"` | | ✅ 排他チェック | Phase 6 オプション同時有効時にエラー | `make CFLAGS="-D... -D..."` | | ✅ 基本動作 | No crash, alloc/free 正常 | `./larson_hakmem 2 ... 1` | | ✅ マルチスレッド | No crash, no A213 | `./larson_hakmem 10 ... 4` | | ✅ パフォーマンス | +10%以上 | Throughput 比較 | | ✅ メモリ安全 | No leaks, no corruption | Guard mode テスト | ### 🚧 既知の課題と対策 #### 課題 1: External 変数の依存 **問題**: Box 5/6 が `g_tls_sll_head` などの extern 変数に依存 **対策**: - hakmem_tiny.c で変数が定義済み → OK - Include 順序を守る(変数定義の後に box を include) #### 課題 2: Backend 関数の依存 **問題**: Box 5 が `sll_refill_small_from_ss()` などに依存 **対策**: - これらの関数は既存の hakmem_tiny.c に存在 → OK - Forward declaration を tiny_alloc_fast.inc.h に追加済み #### 課題 3: Circular Include **問題**: tiny_free_fast.inc.h が slab_handle.h を include、slab_handle.h が tiny_atomic.h を使うべき **対策**: - tiny_atomic.h は最初に include(Layer 0) - Include guard で重複を防止(#pragma once) ### 🔄 Rollback Plan 統合が失敗した場合の切り戻し手順: ```bash # 1. Flag を無効化してビルド make clean make larson_hakmem # → Phase 6 なしの default に戻る # 2. 新ファイルを削除(optional) rm -f core/tiny_atomic.h core/tiny_alloc_fast.inc.h core/tiny_free_fast.inc.h # 3. Git で元に戻す(if needed) git checkout core/hakmem_tiny.c core/hakmem.c ``` ### 📅 タイムライン | Step | 作業 | 時間 | 累計 | |------|------|------|------| | 1.4.1 | Feature flag 設計 | 30分 | 0.5h | | 1.4.2 | hakmem_tiny.c 修正 | 1時間 | 1.5h | | 1.4.3 | hakmem.c 修正 | 1時間 | 2.5h | | 1.4.4 | Makefile 修正 | 30分 | 3h | | 1.5.1 | コンパイル確認 | 30分 | 3.5h | | 1.5.2 | 動作確認テスト | 1時間 | 4.5h | | 1.5.3 | パフォーマンス測定 | 1時間 | 5.5h | **Total**: 約 6時間(Week 1 完了) ### 🎯 Next Steps 1. **今すぐ**: hakmem_tiny.c に Feature flag 追加 2. **次**: hakmem.c の entry points 修正 3. **その後**: ビルド & テスト 4. **最後**: ベンチマーク & 結果レポート --- **Status**: 統合計画完成、実装準備完了 **Risk**: Low(Rollback plan あり、Feature flag で切り戻し可能) **Confidence**: High(既存 Phase 6 パターンと一貫性あり) 🎁 **統合開始準備完了!** 🎁