Files
hakmem/docs/design/REFACTOR_INTEGRATION_PLAN.md
Moe Charm (CI) 67fb15f35f Wrap debug fprintf in !HAKMEM_BUILD_RELEASE guards (Release build optimization)
## Changes

### 1. core/page_arena.c
- Removed init failure message (lines 25-27) - error is handled by returning early
- All other fprintf statements already wrapped in existing #if !HAKMEM_BUILD_RELEASE blocks

### 2. core/hakmem.c
- Wrapped SIGSEGV handler init message (line 72)
- CRITICAL: Kept SIGSEGV/SIGBUS/SIGABRT error messages (lines 62-64) - production needs crash logs

### 3. core/hakmem_shared_pool.c
- Wrapped all debug fprintf statements in #if !HAKMEM_BUILD_RELEASE:
  - Node pool exhaustion warning (line 252)
  - SP_META_CAPACITY_ERROR warning (line 421)
  - SP_FIX_GEOMETRY debug logging (line 745)
  - SP_ACQUIRE_STAGE0.5_EMPTY debug logging (line 865)
  - SP_ACQUIRE_STAGE0_L0 debug logging (line 803)
  - SP_ACQUIRE_STAGE1_LOCKFREE debug logging (line 922)
  - SP_ACQUIRE_STAGE2_LOCKFREE debug logging (line 996)
  - SP_ACQUIRE_STAGE3 debug logging (line 1116)
  - SP_SLOT_RELEASE debug logging (line 1245)
  - SP_SLOT_FREELIST_LOCKFREE debug logging (line 1305)
  - SP_SLOT_COMPLETELY_EMPTY debug logging (line 1316)
- Fixed lock_stats_init() for release builds (lines 60-65) - ensure g_lock_stats_enabled is initialized

## Performance Validation

Before: 51M ops/s (with debug fprintf overhead)
After:  49.1M ops/s (consistent performance, fprintf removed from hot paths)

## Build & Test

```bash
./build.sh larson_hakmem
./out/release/larson_hakmem 1 5 1 1000 100 10000 42
# Result: 49.1M ops/s
```

Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 13:14:18 +09:00

320 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 は最初に includeLayer 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**: LowRollback plan あり、Feature flag で切り戻し可能)
**Confidence**: High既存 Phase 6 パターンと一貫性あり)
🎁 **統合開始準備完了!** 🎁