320 lines
9.3 KiB
Markdown
320 lines
9.3 KiB
Markdown
|
|
# 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 パターンと一貫性あり)
|
|||
|
|
|
|||
|
|
🎁 **統合開始準備完了!** 🎁
|