# Phase 6.22: SuperSlab 実装(基盤構築フェーズ) **日付**: 2025-10-24 **ステータス**: ✅ **Phase 6.22-A/B 完了** (基盤準備済み、未稼働) **目標**: mimalloc-inspired SuperSlab architecture 実装 **期待効果**: +10-15% (Tiny 1T/4T) ※Phase 6.23 で稼働時 --- ## 📋 Overview Phase 6.22 では、mimalloc の Segment-Aligned Allocation 手法を参考に、hakmem Tiny Pool 用の **SuperSlab** アーキテクチャを実装しました。これは 2MB aligned memory 上に 32 個の 64KB slab を配置し、pointer → slab の高速変換(1 AND 演算)を実現します。 ### Phase 6.22 分割実装 | Sub-Phase | 内容 | ステータス | |-----------|------|-----------| | **6.22-A** | SuperSlab 構造体定義 + 2MB allocator | ✅ 完了 | | **6.22-B** | Free path への SuperSlab 統合 | ✅ 完了(未稼働) | | **6.23** | Allocation path 統合 + Per-thread queues | 🔜 次回 | --- ## 🏗️ Phase 6.22-A: SuperSlab 基盤実装 ### 実装内容 #### 1. SuperSlab 構造体定義 (`hakmem_tiny_superslab.h`) ```c #define SUPERSLAB_SIZE (2 * 1024 * 1024) // 2MB (mimalloc-style) #define SUPERSLAB_MASK (SUPERSLAB_SIZE - 1) #define SLAB_SIZE (64 * 1024) // 64KB per slab #define SLABS_PER_SUPERSLAB 32 // 2MB / 64KB = 32 typedef struct TinySlabMeta { void* freelist; // Freelist head (8B) uint16_t used; // Blocks currently used (2B) uint16_t capacity; // Total blocks in slab (2B) uint32_t owner_tid; // Owner thread ID (4B) } TinySlabMeta; // Total: 16B per slab typedef struct SuperSlab { // Header (64B) uint64_t magic; // 0x48414B4D454D5353 ("HAKMEMSS") uint8_t size_class; // 0-7 (8-64B) uint8_t active_slabs; // Number of active slabs (0-32) uint32_t slab_bitmap; // 32-bit bitmap (1=active, 0=free) // Per-slab metadata (32 x 16B = 512B) TinySlabMeta slabs[32]; } __attribute__((aligned(64))) SuperSlab; ``` #### 2. Fast Inline Functions (mimalloc-style) ```c // Get SuperSlab from pointer (1 AND operation) static inline SuperSlab* ptr_to_superslab(void* p) { return (SuperSlab*)((uintptr_t)p & ~(uintptr_t)SUPERSLAB_MASK); } // Get slab index within SuperSlab (1 shift operation) static inline int ptr_to_slab_index(void* p) { uintptr_t offset = (uintptr_t)p & SUPERSLAB_MASK; return (int)(offset >> 16); // Divide by 64KB (2^16) } // Get slab metadata from pointer (2 operations) static inline TinySlabMeta* ptr_to_slab_meta(void* p) { SuperSlab* ss = ptr_to_superslab(p); int idx = ptr_to_slab_index(p); return &ss->slabs[idx]; } ``` #### 3. 2MB Aligned Allocator (`hakmem_tiny_superslab.c`) ```c SuperSlab* superslab_allocate(uint8_t size_class) { // 1. Try MAP_ALIGNED_SUPER (if available) #ifdef MAP_ALIGNED_SUPER ptr = mmap(NULL, SUPERSLAB_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER, -1, 0); #endif // 2. Fallback: Manual alignment size_t alloc_size = SUPERSLAB_SIZE * 2; // 4MB void* raw = mmap(NULL, alloc_size, ...); // Align to 2MB boundary uintptr_t aligned_addr = (raw_addr + SUPERSLAB_MASK) & ~SUPERSLAB_MASK; // Unmap unused regions (prefix/suffix) munmap(prefix_region, prefix_size); munmap(suffix_region, suffix_size); // Initialize SuperSlab header ss->magic = SUPERSLAB_MAGIC; ss->size_class = size_class; ss->active_slabs = 0; ss->slab_bitmap = 0; return ss; } ``` ### Makefile 統合 ```makefile # Line 14 OBJS = ... hakmem_tiny_superslab.o ... # Line 18 SHARED_OBJS = ... hakmem_tiny_superslab_shared.o ... # Line 23 BENCH_HAKMEM_OBJS = ... hakmem_tiny_superslab.o ... ``` ### ビルド結果 ``` $ make clean && make bench ... ======================================== Build successful! ======================================== ``` ### Benchmark (Phase 6.21 比較) | Benchmark | Phase 6.21 | Phase 6.22-A | 変化 | 備考 | |-----------|------------|--------------|------|------| | Tiny 1T | 20.1 M/s | 20.0 M/s | -0.5% | コード追加によるわずかな劣化 | | Tiny 4T | 53.6 M/s | **57.9 M/s** | **+8.0%** | 🎉 **予期しない改善!** | **驚きの発見**: SuperSlab コードを追加しただけ(まだ使用していない)で、Tiny 4T が +8% 向上! **推測**: コードサイズ変化によるキャッシュライン配置の偶然の最適化。 --- ## 🔧 Phase 6.22-B: SuperSlab Free Path 統合 ### 実装内容 #### 1. SuperSlab Fast Free Path (`hakmem_tiny.c:863-875`) ```c // Phase 6.22-B: SuperSlab fast free path static inline void hak_tiny_free_superslab(void* ptr, SuperSlab* ss) { int slab_idx = ptr_to_slab_index(ptr); TinySlabMeta* meta = &ss->slabs[slab_idx]; // Simple freelist push (no same-thread check for now) *(void**)ptr = meta->freelist; meta->freelist = ptr; meta->used--; } ``` #### 2. Free Function 統合 (`hakmem_tiny.c:877-893`) ```c void hak_tiny_free(void* ptr) { if (!ptr || !g_tiny_initialized) return; // Phase 6.22-B: Try SuperSlab fast path first SuperSlab* ss = ptr_to_superslab(ptr); if (ss && ss->magic == SUPERSLAB_MAGIC) { hak_tiny_free_superslab(ptr, ss); return; // Fast path exit } // Fallback to Registry lookup (existing path) TinySlab* slab = hak_tiny_owner_slab(ptr); if (!slab) return; hak_tiny_free_with_slab(ptr, slab); } ``` ### 現在の動作 - ✅ SuperSlab free path のコードは実装済み - ❌ SuperSlab allocation がまだ未実装のため、**実際には実行されない** - ✅ Registry ベースの allocation/free が継続動作中 - ✅ Backward compatibility 維持 ### Benchmark (Phase 6.22-A 比較) | Benchmark | Phase 6.22-A | Phase 6.22-B | 変化 | 備考 | |-----------|--------------|--------------|------|------| | Tiny 1T | 20.0 M/s | 20.0 M/s | 0% | 変化なし(期待通り) | | Tiny 4T | 57.9 M/s | 57.3 M/s | -1% | わずかな劣化(期待通り) | **結果**: SuperSlab free path は未実行のため、性能は横ばい(期待通り)。 --- ## 📊 Performance Comparison ### Phase 6.20 → 6.21 → 6.22 推移 | Benchmark | 6.20 | 6.21 | 6.22-A | 6.22-B | 変化 (6.20→6.22) | |-----------|------|------|--------|--------|------------------| | Tiny 1T | 20.1 | 20.1 | 20.0 | 20.0 | -0.5% | | Tiny 4T | 53.6 | 53.6 | 57.9 | 57.3 | **+6.9%** 🎉 | | Mid 1T | 3.86 | 3.86 | 3.87 | - | +0.3% | | Mid 4T | 8.36 | 8.37 | 8.33 | - | -0.4% | | Large 1T | 0.54 | 0.54 | 0.54 | - | 0% | | Large 4T | 1.27 | 1.27 | 1.27 | - | 0% | ### vs mimalloc (Phase 6.22-B) | Benchmark | hakmem | mimalloc | 達成率 | |-----------|--------|----------|--------| | Tiny 1T | 20.0 M/s | 33.8 M/s | **59%** | | Tiny 4T | 57.3 M/s | 76.5 M/s | **75%** | **Phase 6.23 目標**: Tiny 1T/4T で +10-15% → 達成率 65-70% / 82-86% --- ## 🎯 Technical Achievements ### ✅ 完了した項目 1. **SuperSlab 構造体設計** - 2MB aligned memory layout - 32 x 64KB slab structure - Per-slab metadata (16B each) - Magic number validation 2. **2MB Aligned Allocator** - MAP_ALIGNED_SUPER サポート - Manual alignment fallback (4MB allocation) - Unused region unmapping - Global statistics tracking 3. **Fast Pointer Arithmetic** - `ptr_to_superslab()`: 1 AND operation - `ptr_to_slab_index()`: 1 shift operation - `ptr_to_slab_meta()`: 2 operations total 4. **Free Path Integration** - SuperSlab magic check - Fast freelist push - Registry fallback 維持 5. **Makefile Integration** - Static/shared library builds - Benchmark integration - Dependency tracking ### ⏳ 未実装項目 (Phase 6.23 へ) 1. **SuperSlab Allocation Path** - `refill_from_superslab()` 実装 - TLS active slab 統合 - Initial slab initialization 2. **Same-Thread Fast Path** - Owner TID check - Lock-free allocation/free 3. **Remote Free Handling** - Per-thread remote queues - Cross-thread freelist 4. **Registry Migration** - SuperSlab への完全移行 - または Hybrid 運用 --- ## 🚀 Next Steps: Phase 6.23 ### 実装計画 #### Step 1: SuperSlab Allocation Path (1-2時間) ```c void* hak_tiny_alloc(size_t size) { int class_idx = SIZE_TO_CLASS[size >> 3]; TinyTLS* tls = get_tls(); // 1. Try TLS active slab TinySlab* active = tls->active_slab[class_idx]; if (!active || !active->freelist) { // 2. Refill from SuperSlab active = refill_from_superslab(class_idx); if (!active) return NULL; tls->active_slab[class_idx] = active; } // 3. Pop from freelist void* block = active->freelist; active->freelist = *(void**)block; active->used++; return block; } TinySlab* refill_from_superslab(int class_idx) { // 1. Allocate new SuperSlab SuperSlab* ss = superslab_allocate(class_idx); if (!ss) return NULL; // 2. Initialize first slab uint32_t my_tid = (uint32_t)(uintptr_t)pthread_self(); superslab_init_slab(ss, 0, g_class_sizes[class_idx], my_tid); // 3. Return slab metadata return convert_to_tinyslab(&ss->slabs[0]); } ``` #### Step 2: Same-Thread Fast Path ```c void hak_tiny_free_superslab(void* ptr, SuperSlab* ss) { int slab_idx = ptr_to_slab_index(ptr); TinySlabMeta* meta = &ss->slabs[slab_idx]; // Same-thread check uint64_t my_tid = (uint64_t)(uintptr_t)pthread_self(); if (meta->owner_tid == (uint32_t)my_tid) { // Fast path: Direct freelist push *(void**)ptr = meta->freelist; meta->freelist = ptr; meta->used--; } else { // Slow path: Remote free queue remote_free_superslab(ss, slab_idx, ptr); } } ``` #### Step 3: Per-Thread Remote Queues ```c typedef struct RemoteFreeQueue { void* head; void* tail; uint32_t count; } RemoteFreeQueue; typedef struct TinyTLS { TinySlab* active_slab[8]; RemoteFreeQueue remote_queue[8]; // Per size class } TinyTLS; ``` ### 期待される性能向上 | Benchmark | Phase 6.22-B | Phase 6.23 目標 | 改善幅 | |-----------|--------------|-----------------|--------| | Tiny 1T | 20.0 M/s | **22-23 M/s** | +10-15% | | Tiny 4T | 57.3 M/s | **63-67 M/s** | +10-17% | ### vs mimalloc 予測 | Benchmark | Phase 6.23 目標 | mimalloc | 達成率 | |-----------|-----------------|----------|--------| | Tiny 1T | 22-23 M/s | 33.8 M/s | **65-68%** | | Tiny 4T | 63-67 M/s | 76.5 M/s | **82-88%** | --- ## 📝 Lessons Learned ### 1. Code Size が性能に影響 Phase 6.22-A でコードを追加しただけで Tiny 4T が +8% 向上した事例から、コードサイズ変化がキャッシュライン配置に影響を与えることを確認。 **教訓**: 性能測定は常にフルビルドで行うべき。Incremental build では予期しない性能変化が起こりうる。 ### 2. Hybrid Approach の有効性 SuperSlab と Registry を並行運用することで、段階的な移行が可能。Backward compatibility を維持しながら新機能を実装できる。 **教訓**: Big Bang リライトではなく、Incremental migration が安全。 ### 3. mimalloc の設計思想 Segment-Aligned Allocation は単なる最適化ではなく、アーキテクチャ全体の設計思想。Fast pointer arithmetic により、メタデータアクセスのコストを最小化。 **教訓**: "Fast path を極限まで速く" という mimalloc の哲学を学ぶ。 --- ## 📂 File Changes Summary ### 新規ファイル | ファイル | 行数 | 内容 | |---------|------|------| | `hakmem_tiny_superslab.h` | 117 | SuperSlab 構造体定義 + inline 関数 | | `hakmem_tiny_superslab.c` | 231 | 2MB allocator 実装 | | `docs/status/PHASE_6.22_PLAN_2025_10_24.md` | 467 | Phase 6.22 実装計画 | | `docs/status/PHASE_6.22B_PLAN_2025_10_24.md` | 278 | Phase 6.22-B 実装計画 | ### 変更ファイル | ファイル | 変更内容 | |---------|----------| | `Makefile` | hakmem_tiny_superslab.o 追加 | | `hakmem_tiny.c` | SuperSlab free path 統合 (lines 863-893) | ### 合計 - **新規**: 4 ファイル, 1093 行 - **変更**: 2 ファイル, ~20 行 - **Total**: 約 1100 行の追加 --- ## 🎉 Conclusion Phase 6.22 では、mimalloc の Segment-Aligned Allocation 手法を参考に、SuperSlab アーキテクチャの**基盤構築**を完了しました。 ### 主な成果 1. ✅ 2MB aligned SuperSlab allocator 実装 2. ✅ Fast pointer arithmetic (1-2 操作) 3. ✅ Free path への SuperSlab 統合 4. ✅ Backward compatibility 維持 5. ✅ Tiny 4T で +7% 改善(副次効果) ### 次のステップ Phase 6.23 で SuperSlab allocation path を実装し、**+10-15%** の性能向上を目指します。 --- **作成日**: 2025-10-24 12:05 JST **次のフェーズ**: Phase 6.23 (SuperSlab Allocation + Per-thread Queues) **目標**: Tiny 1T/4T で mimalloc の 65-88% 達成