2025-11-09 22:12:34 +09:00
|
|
|
|
# Current Task: Phase 7 + Pool TLS — Step 4.x Integration & Validation(Tiny P0: デフォルトON)
|
2025-11-05 16:47:04 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
**Date**: 2025-11-09
|
|
|
|
|
|
**Status**: 🚀 In Progress (Step 4.x)
|
|
|
|
|
|
**Priority**: HIGH
|
2025-11-08 01:35:45 +09:00
|
|
|
|
|
2025-11-08 03:18:17 +09:00
|
|
|
|
---
|
2025-11-08 01:35:45 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
## 🎯 Goal
|
2025-11-08 04:50:41 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
Box理論に沿って、Pool TLS を中心に「syscall 希薄化」と「境界一箇所化」を推し進め、Tiny/Mid/Larson の安定高速化を図る。
|
2025-11-08 04:50:41 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
### **Why This Works**
|
|
|
|
|
|
Phase 7 Task 3 achieved **+180-280% improvement** by pre-warming:
|
|
|
|
|
|
- **Before**: First allocation → TLS miss → SuperSlab refill (100+ cycles)
|
|
|
|
|
|
- **After**: First allocation → TLS hit (15 cycles, pre-populated cache)
|
2025-11-08 04:50:41 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
**Same bottleneck exists in Pool TLS**:
|
|
|
|
|
|
- First 8KB allocation → TLS miss → Arena carve → mmap (1000+ cycles)
|
|
|
|
|
|
- Pre-warm eliminates this cold-start penalty
|
2025-11-08 04:50:41 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
---
|
2025-11-08 04:50:41 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
## 📊 Current Status(Step 4までの主な進捗)
|
2025-11-08 04:50:41 +09:00
|
|
|
|
|
2025-11-09 22:12:34 +09:00
|
|
|
|
### 実装サマリ(Tiny + Pool TLS)
|
2025-11-09 18:55:50 +09:00
|
|
|
|
- ✅ Tiny 1024B 特例(ヘッダ無し)+ class7 補給の軽量適応(mmap 多発の主因を遮断)
|
|
|
|
|
|
- ✅ OS 降下の境界化(`hak_os_map_boundary()`):mmap 呼び出しを一箇所に集約
|
|
|
|
|
|
- ✅ Pool TLS Arena(1→2→4→8MB指数成長, ENV で可変):mmap をアリーナへ集約
|
|
|
|
|
|
- ✅ Page Registry(チャンク登録/lookup で owner 解決)
|
|
|
|
|
|
- ✅ Remote Queue(Pool 用, mutex バケット版)+ alloc 前の軽量 drain を配線
|
2025-11-08 04:50:41 +09:00
|
|
|
|
|
2025-11-09 22:12:34 +09:00
|
|
|
|
#### Tiny P0(Batch Refill)
|
|
|
|
|
|
- ✅ P0 致命バグ修正(freelist→SLL一括移送後に `meta->used += from_freelist` が抜けていた)
|
|
|
|
|
|
- ✅ 線形 carve の Fail‑Fast ガード(簡素/一般/TLSバンプの全経路)
|
|
|
|
|
|
- ✅ ランタイム A/B スイッチ実装:
|
|
|
|
|
|
- 既定ON(`HAKMEM_TINY_P0_ENABLE` 未設定/≠0)
|
|
|
|
|
|
- Kill: `HAKMEM_TINY_P0_DISABLE=1`、Drain 切替: `HAKMEM_TINY_P0_NO_DRAIN=1`、ログ: `HAKMEM_TINY_P0_LOG=1`
|
|
|
|
|
|
- ✅ ベンチ: 100k×256B(1T)で P0 ON 最速(~2.76M ops/s)、P0 OFF ~2.73M ops/s(安定)
|
|
|
|
|
|
- ⚠️ 既知: `[P0_COUNTER_MISMATCH]` 警告(active_delta と taken の差分)が稀に出るが、SEGV は解消済(継続監査)
|
|
|
|
|
|
|
2025-11-10 00:25:02 +09:00
|
|
|
|
##### NEW: P0 carve ループの根本原因と修正(SEGV 解消)
|
|
|
|
|
|
- 🔴 根因: P0 バッチ carve ループ内で `superslab_refill(class_idx)` により TLS が新しい SuperSlab を指すのに、`tls` を再読込せず `meta=tls->meta` のみ更新 → `ss_active_add(tls->ss, batch)` が古い SuperSlab に加算され、active カウンタ破壊・SEGV に繋がる。
|
|
|
|
|
|
- 🛠 修正: `superslab_refill()` 後に `tls = &g_tls_slabs[class_idx]; meta = tls->meta;` を再読込(core/hakmem_tiny_refill_p0.inc.h)。
|
|
|
|
|
|
- 🧪 検証: 固定サイズ 256B/1KB (200k iters)完走、SEGV 再現なし。active_delta=0 を確認。RS はわずかに改善(0.8–0.9% → 継続最適化対象)。
|
|
|
|
|
|
|
2025-11-09 22:12:34 +09:00
|
|
|
|
詳細: docs/TINY_P0_BATCH_REFILL.md
|
|
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
---
|
2025-11-08 04:50:41 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
## 🚀 次のステップ(アクション)
|
2025-11-08 04:50:41 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
1) Remote Queue の drain を Pool TLS refill 境界とも統合(低水位時は drain→refill→bind)
|
|
|
|
|
|
- 現状: pool_alloc 入口で drain, pop 後 low-water で追加 drain を実装済み
|
|
|
|
|
|
- 追加: refill 経路(`pool_refill_and_alloc` 呼出し直前)でも drain を試行し、drain 成功時は refill を回避
|
2025-11-05 12:31:14 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
2) strace による syscall 減少確認(指標化)
|
|
|
|
|
|
- RandomMixed: 256 / 1024B, それぞれ `mmap/madvise/munmap` 回数(-c合計)
|
|
|
|
|
|
- PoolTLS: 1T/4T の `mmap/madvise/munmap` 減少を比較(Arena導入前後)
|
2025-11-08 01:35:45 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
3) 性能A/B(ENV: INIT/MAX/GROWTH)で最適化勘所を探索
|
|
|
|
|
|
- `HAKMEM_POOL_TLS_ARENA_MB_INIT`, `HAKMEM_POOL_TLS_ARENA_MB_MAX`, `HAKMEM_POOL_TLS_ARENA_GROWTH_LEVELS` の組合せを評価
|
|
|
|
|
|
- 目標: syscall を削減しつつメモリ使用量を許容範囲に維持
|
|
|
|
|
|
|
|
|
|
|
|
4) Remote Queue の高速化(次フェーズ)
|
2025-11-10 00:25:02 +09:00
|
|
|
|
|
|
|
|
|
|
5) Tiny 256B/1KB の直詰め最適化(性能)
|
|
|
|
|
|
- P0→FC 直詰めの一往復設計を活用し、以下を段階的に適用(A/Bスイッチ済み)
|
|
|
|
|
|
- FC cap/batch 上限の掃引(class5/7)
|
|
|
|
|
|
- remote drain 閾値化のチューニング(頻度削減)
|
|
|
|
|
|
- adopt 先行の徹底(map 前に再試行)
|
|
|
|
|
|
- 配列詰めの軽い unroll/分岐ヒントの見直し(branch‑miss 低減)
|
2025-11-09 18:55:50 +09:00
|
|
|
|
- まずはmutex→lock分割/軽量スピン化、必要に応じてクラス別queue
|
|
|
|
|
|
- Page Registry の O(1) 化(ページ単位のテーブル), 将来はper-arena ID化
|
|
|
|
|
|
|
2025-11-10 00:25:02 +09:00
|
|
|
|
### NEW: 本日の適用と計測スナップショット(Ryzen 7 5825U)
|
|
|
|
|
|
- 変更点(Tiny 256B/1KB 向け)
|
|
|
|
|
|
- FastCache 有効容量を per-class で厳密適用(`tiny_fc_room/push_bulk` が `g_fast_cap[c]` を使用)
|
|
|
|
|
|
- 既定 cap 見直し: class5=96, class7=48(ENVで上書き可: `HAKMEM_TINY_FAST_CAP_C{5,7}`)
|
|
|
|
|
|
- Direct-FC の drain 閾値 既定を 32→64(ENV: `HAKMEM_TINY_P0_DRAIN_THRESH`)
|
|
|
|
|
|
- class7 の Direct-FC 既定は OFF(`HAKMEM_TINY_P0_DIRECT_FC_C7=1` で明示ON)
|
|
|
|
|
|
|
|
|
|
|
|
- 固定サイズベンチ(release, 200k iters)
|
|
|
|
|
|
- 256B: 4.49–4.54M ops/s, branch-miss ≈ 8.89%(先行値 ≈11% から改善)
|
|
|
|
|
|
- 1KB: 現状 SEGV(Direct-FC OFF でも再現)→ P0 一般経路の残存不具合の可能性
|
|
|
|
|
|
- 結果保存: benchmarks/results/<date>_ryzen7-5825U_fixed/
|
|
|
|
|
|
|
|
|
|
|
|
- 推奨: class7 は当面 P0 をA/Bで停止(`HAKMEM_TINY_P0_DISABLE=1` もしくは class7限定ガード導入)し、256Bのチューニングを先行。
|
|
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
**Challenge**: Pool blocks are LARGE (8KB-52KB) vs Tiny (128B-1KB)
|
|
|
|
|
|
|
|
|
|
|
|
**Memory Budget Analysis**:
|
|
|
|
|
|
```
|
|
|
|
|
|
Phase 7 Tiny:
|
|
|
|
|
|
- 16 blocks × 1KB = 16KB per class
|
|
|
|
|
|
- 7 classes × 16KB = 112KB total ✅ Acceptable
|
|
|
|
|
|
|
|
|
|
|
|
Pool TLS (Naive):
|
|
|
|
|
|
- 16 blocks × 8KB = 128KB (class 0)
|
|
|
|
|
|
- 16 blocks × 52KB = 832KB (class 6)
|
|
|
|
|
|
- Total: ~4-5MB ❌ Too much!
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**Smart Strategy**: Variable pre-warm counts based on expected usage
|
|
|
|
|
|
```c
|
|
|
|
|
|
// Hot classes (8-24KB) - common in real workloads
|
|
|
|
|
|
Class 0 (8KB): 16 blocks = 128KB
|
|
|
|
|
|
Class 1 (16KB): 16 blocks = 256KB
|
|
|
|
|
|
Class 2 (24KB): 12 blocks = 288KB
|
|
|
|
|
|
|
|
|
|
|
|
// Warm classes (32-40KB)
|
|
|
|
|
|
Class 3 (32KB): 8 blocks = 256KB
|
|
|
|
|
|
Class 4 (40KB): 8 blocks = 320KB
|
2025-11-08 03:18:17 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
// Cold classes (48-52KB) - rare
|
|
|
|
|
|
Class 5 (48KB): 4 blocks = 192KB
|
|
|
|
|
|
Class 6 (52KB): 4 blocks = 208KB
|
2025-11-08 04:50:41 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
Total: ~1.6MB ✅ Acceptable
|
|
|
|
|
|
```
|
2025-11-08 01:35:45 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
**Rationale**:
|
|
|
|
|
|
1. Smaller classes are used more frequently (Pareto principle)
|
|
|
|
|
|
2. Total memory: 1.6MB (reasonable for 8-52KB allocations)
|
|
|
|
|
|
3. Covers most real-world workload patterns
|
2025-11-08 01:35:45 +09:00
|
|
|
|
|
2025-11-08 23:53:25 +09:00
|
|
|
|
---
|
2025-11-08 01:35:45 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
## ENV(Arena 関連)
|
|
|
|
|
|
```
|
|
|
|
|
|
# Initial chunk size in MB (default: 1)
|
|
|
|
|
|
export HAKMEM_POOL_TLS_ARENA_MB_INIT=2
|
|
|
|
|
|
|
|
|
|
|
|
# Maximum chunk size in MB (default: 8)
|
|
|
|
|
|
export HAKMEM_POOL_TLS_ARENA_MB_MAX=16
|
|
|
|
|
|
|
|
|
|
|
|
# Number of growth levels (default: 3 → 1→2→4→8MB)
|
|
|
|
|
|
export HAKMEM_POOL_TLS_ARENA_GROWTH_LEVELS=4
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**Location**: `core/pool_tls.c`
|
|
|
|
|
|
|
|
|
|
|
|
**Code**:
|
|
|
|
|
|
```c
|
|
|
|
|
|
// Pre-warm counts optimized for memory usage
|
|
|
|
|
|
static const int PREWARM_COUNTS[POOL_SIZE_CLASSES] = {
|
|
|
|
|
|
16, 16, 12, // Hot: 8KB, 16KB, 24KB
|
|
|
|
|
|
8, 8, // Warm: 32KB, 40KB
|
|
|
|
|
|
4, 4 // Cold: 48KB, 52KB
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
void pool_tls_prewarm(void) {
|
|
|
|
|
|
for (int class_idx = 0; class_idx < POOL_SIZE_CLASSES; class_idx++) {
|
|
|
|
|
|
int count = PREWARM_COUNTS[class_idx];
|
|
|
|
|
|
size_t size = POOL_CLASS_SIZES[class_idx];
|
|
|
|
|
|
|
|
|
|
|
|
// Allocate then immediately free to populate TLS cache
|
|
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
|
|
|
|
void* ptr = pool_alloc(size);
|
|
|
|
|
|
if (ptr) {
|
|
|
|
|
|
pool_free(ptr); // Goes back to TLS freelist
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// OOM during pre-warm (rare, but handle gracefully)
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**Header Addition** (`core/pool_tls.h`):
|
|
|
|
|
|
```c
|
|
|
|
|
|
// Pre-warm TLS cache (call once at thread init)
|
|
|
|
|
|
void pool_tls_prewarm(void);
|
|
|
|
|
|
```
|
2025-11-08 01:35:45 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 軽い確認(推奨)
|
|
|
|
|
|
```
|
|
|
|
|
|
# PoolTLS
|
|
|
|
|
|
./build.sh bench_pool_tls_hakmem
|
|
|
|
|
|
./bench_pool_tls_hakmem 1 100000 256 42
|
|
|
|
|
|
./bench_pool_tls_hakmem 4 50000 256 42
|
|
|
|
|
|
|
|
|
|
|
|
# syscall 計測(mmap/madvise/munmap 合計が減っているか確認)
|
|
|
|
|
|
strace -e trace=mmap,madvise,munmap -c ./bench_pool_tls_hakmem 1 100000 256 42
|
|
|
|
|
|
strace -e trace=mmap,madvise,munmap -c ./bench_random_mixed_hakmem 100000 256 42
|
|
|
|
|
|
strace -e trace=mmap,madvise,munmap -c ./bench_random_mixed_hakmem 100000 1024 42
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**Location**: `core/hakmem.c` (or wherever Pool TLS init happens)
|
|
|
|
|
|
|
|
|
|
|
|
**Code**:
|
|
|
|
|
|
```c
|
|
|
|
|
|
#ifdef HAKMEM_POOL_TLS_PHASE1
|
|
|
|
|
|
// Initialize Pool TLS
|
|
|
|
|
|
pool_thread_init();
|
|
|
|
|
|
|
|
|
|
|
|
// Pre-warm cache (Phase 1.5b optimization)
|
|
|
|
|
|
#ifdef HAKMEM_POOL_TLS_PREWARM
|
|
|
|
|
|
pool_tls_prewarm();
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#endif
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**Makefile Addition**:
|
|
|
|
|
|
```makefile
|
|
|
|
|
|
# Pool TLS Phase 1.5b - Pre-warm optimization
|
|
|
|
|
|
ifeq ($(POOL_TLS_PREWARM),1)
|
|
|
|
|
|
CFLAGS += -DHAKMEM_POOL_TLS_PREWARM=1
|
|
|
|
|
|
endif
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**Update `build.sh`**:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
make \
|
|
|
|
|
|
POOL_TLS_PHASE1=1 \
|
|
|
|
|
|
POOL_TLS_PREWARM=1 \ # NEW!
|
|
|
|
|
|
HEADER_CLASSIDX=1 \
|
|
|
|
|
|
AGGRESSIVE_INLINE=1 \
|
|
|
|
|
|
PREWARM_TLS=1 \
|
|
|
|
|
|
"${TARGET}"
|
|
|
|
|
|
```
|
2025-11-08 01:35:45 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
---
|
2025-11-08 03:18:17 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
### **Step 4: Build & Smoke Test** ⏳ 10 min
|
2025-11-08 01:35:45 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
```bash
|
|
|
|
|
|
# Build with pre-warm enabled
|
|
|
|
|
|
./build_pool_tls.sh bench_mid_large_mt_hakmem
|
2025-11-05 12:31:14 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
# Quick smoke test
|
|
|
|
|
|
./dev_pool_tls.sh test
|
2025-11-08 23:53:25 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
# Expected: No crashes, similar or better performance
|
|
|
|
|
|
```
|
2025-11-05 12:31:14 +09:00
|
|
|
|
|
feat: Phase 7 + Phase 2 - Massive performance & stability improvements
Performance Achievements:
- Tiny allocations: +180-280% (21M → 59-70M ops/s random mixed)
- Single-thread: +24% (2.71M → 3.36M ops/s Larson)
- 4T stability: 0% → 95% (19/20 success rate)
- Overall: 91.3% of System malloc average (target was 40-55%) ✓
Phase 7 (Tasks 1-3): Core Optimizations
- Task 1: Header validation removal (Region-ID direct lookup)
- Task 2: Aggressive inline (TLS cache access optimization)
- Task 3: Pre-warm TLS cache (eliminate cold-start penalty)
Result: +180-280% improvement, 85-146% of System malloc
Critical Bug Fixes:
- Fix 64B allocation crash (size-to-class +1 for header)
- Fix 4T wrapper recursion bugs (BUG #7, #8, #10, #11)
- Remove malloc fallback (30% → 50% stability)
Phase 2a: SuperSlab Dynamic Expansion (CRITICAL)
- Implement mimalloc-style chunk linking
- Unlimited slab expansion (no more OOM at 32 slabs)
- Fix chunk initialization bug (bitmap=0x00000001 after expansion)
Files: core/hakmem_tiny_superslab.c/h, core/superslab/superslab_types.h
Result: 50% → 95% stability (19/20 4T success)
Phase 2b: TLS Cache Adaptive Sizing
- Dynamic capacity: 16-2048 slots based on usage
- High-water mark tracking + exponential growth/shrink
- Expected: +3-10% performance, -30-50% memory
Files: core/tiny_adaptive_sizing.c/h (new)
Phase 2c: BigCache Dynamic Hash Table
- Migrate from fixed 256×8 array to dynamic hash table
- Auto-resize: 256 → 512 → 1024 → 65,536 buckets
- Improved hash function (FNV-1a) + collision chaining
Files: core/hakmem_bigcache.c/h
Expected: +10-20% cache hit rate
Design Flaws Analysis:
- Identified 6 components with fixed-capacity bottlenecks
- SuperSlab (CRITICAL), TLS Cache (HIGH), BigCache/L2.5 (MEDIUM)
- Report: DESIGN_FLAWS_ANALYSIS.md (11 chapters)
Documentation:
- 13 comprehensive reports (PHASE*.md, DESIGN_FLAWS*.md)
- Implementation guides, test results, production readiness
- Bug fix reports, root cause analysis
Build System:
- Makefile: phase7 targets, PREWARM_TLS flag
- Auto dependency generation (-MMD -MP) for .inc files
Known Issues:
- 4T stability: 19/20 (95%) - investigating 1 failure for 100%
- L2.5 Pool dynamic sharding: design only (needs 2-3 days integration)
🤖 Generated with Claude Code (https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 17:08:00 +09:00
|
|
|
|
---
|
2025-11-08 03:18:17 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
### **Step 5: Benchmark** ⏳ 15 min
|
2025-11-08 23:53:25 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
```bash
|
|
|
|
|
|
# Full benchmark vs System malloc
|
|
|
|
|
|
./run_pool_bench.sh
|
feat: Phase 7 + Phase 2 - Massive performance & stability improvements
Performance Achievements:
- Tiny allocations: +180-280% (21M → 59-70M ops/s random mixed)
- Single-thread: +24% (2.71M → 3.36M ops/s Larson)
- 4T stability: 0% → 95% (19/20 success rate)
- Overall: 91.3% of System malloc average (target was 40-55%) ✓
Phase 7 (Tasks 1-3): Core Optimizations
- Task 1: Header validation removal (Region-ID direct lookup)
- Task 2: Aggressive inline (TLS cache access optimization)
- Task 3: Pre-warm TLS cache (eliminate cold-start penalty)
Result: +180-280% improvement, 85-146% of System malloc
Critical Bug Fixes:
- Fix 64B allocation crash (size-to-class +1 for header)
- Fix 4T wrapper recursion bugs (BUG #7, #8, #10, #11)
- Remove malloc fallback (30% → 50% stability)
Phase 2a: SuperSlab Dynamic Expansion (CRITICAL)
- Implement mimalloc-style chunk linking
- Unlimited slab expansion (no more OOM at 32 slabs)
- Fix chunk initialization bug (bitmap=0x00000001 after expansion)
Files: core/hakmem_tiny_superslab.c/h, core/superslab/superslab_types.h
Result: 50% → 95% stability (19/20 4T success)
Phase 2b: TLS Cache Adaptive Sizing
- Dynamic capacity: 16-2048 slots based on usage
- High-water mark tracking + exponential growth/shrink
- Expected: +3-10% performance, -30-50% memory
Files: core/tiny_adaptive_sizing.c/h (new)
Phase 2c: BigCache Dynamic Hash Table
- Migrate from fixed 256×8 array to dynamic hash table
- Auto-resize: 256 → 512 → 1024 → 65,536 buckets
- Improved hash function (FNV-1a) + collision chaining
Files: core/hakmem_bigcache.c/h
Expected: +10-20% cache hit rate
Design Flaws Analysis:
- Identified 6 components with fixed-capacity bottlenecks
- SuperSlab (CRITICAL), TLS Cache (HIGH), BigCache/L2.5 (MEDIUM)
- Report: DESIGN_FLAWS_ANALYSIS.md (11 chapters)
Documentation:
- 13 comprehensive reports (PHASE*.md, DESIGN_FLAWS*.md)
- Implementation guides, test results, production readiness
- Bug fix reports, root cause analysis
Build System:
- Makefile: phase7 targets, PREWARM_TLS flag
- Auto dependency generation (-MMD -MP) for .inc files
Known Issues:
- 4T stability: 19/20 (95%) - investigating 1 failure for 100%
- L2.5 Pool dynamic sharding: design only (needs 2-3 days integration)
🤖 Generated with Claude Code (https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 17:08:00 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
# Expected results:
|
|
|
|
|
|
# Before (1.5a): 1.79M ops/s
|
|
|
|
|
|
# After (1.5b): 5-15M ops/s (+3-8x)
|
|
|
|
|
|
```
|
2025-11-08 03:18:17 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
**Additional benchmarks**:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# Different sizes
|
|
|
|
|
|
./bench_mid_large_mt_hakmem 1 100000 256 42 # 8-32KB mixed
|
|
|
|
|
|
./bench_mid_large_mt_hakmem 1 100000 1024 42 # Larger workset
|
2025-11-08 04:50:41 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
# Multi-threaded
|
|
|
|
|
|
./bench_mid_large_mt_hakmem 4 100000 256 42 # 4T
|
|
|
|
|
|
```
|
2025-11-05 12:31:14 +09:00
|
|
|
|
|
2025-11-08 01:35:45 +09:00
|
|
|
|
---
|
2025-11-05 12:31:14 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
### **Step 6: Measure & Analyze** ⏳ 10 min
|
|
|
|
|
|
|
|
|
|
|
|
**Metrics to collect**:
|
|
|
|
|
|
1. ops/s improvement (target: +3-8x)
|
|
|
|
|
|
2. Memory overhead (should be ~1.6MB per thread)
|
|
|
|
|
|
3. Cold-start penalty reduction (first allocation latency)
|
|
|
|
|
|
|
|
|
|
|
|
**Success Criteria**:
|
|
|
|
|
|
- ✅ No crashes or stability issues
|
|
|
|
|
|
- ✅ +200% or better improvement (5M ops/s minimum)
|
|
|
|
|
|
- ✅ Memory overhead < 2MB per thread
|
|
|
|
|
|
- ✅ No performance regression on small workloads
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### **Step 7: Tune (if needed)** ⏳ 15 min (optional)
|
|
|
|
|
|
|
|
|
|
|
|
**If results are suboptimal**, adjust pre-warm counts:
|
2025-11-05 12:31:14 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
**Too slow** (< 5M ops/s):
|
|
|
|
|
|
- Increase hot class pre-warm (16 → 24)
|
|
|
|
|
|
- More aggressive: Pre-warm all classes to 16
|
2025-11-05 12:31:14 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
**Memory too high** (> 2MB):
|
|
|
|
|
|
- Reduce cold class pre-warm (4 → 2)
|
|
|
|
|
|
- Lazy pre-warm: Only hot classes initially
|
2025-11-08 03:18:17 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
**Adaptive approach**:
|
|
|
|
|
|
```c
|
|
|
|
|
|
// Pre-warm based on runtime heuristics
|
|
|
|
|
|
void pool_tls_prewarm_adaptive(void) {
|
|
|
|
|
|
// Start with minimal pre-warm
|
|
|
|
|
|
static const int MIN_PREWARM[7] = {8, 8, 4, 4, 2, 2, 2};
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: Track usage patterns and adjust dynamically
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
2025-11-08 03:18:17 +09:00
|
|
|
|
|
|
|
|
|
|
---
|
2025-11-08 01:35:45 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
## 📋 **Implementation Checklist**
|
|
|
|
|
|
|
|
|
|
|
|
### **Phase 1.5b: Pre-warm Optimization**
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 1**: Design pre-warm strategy (15 min)
|
|
|
|
|
|
- [ ] Analyze memory budget
|
|
|
|
|
|
- [ ] Decide pre-warm counts per class
|
|
|
|
|
|
- [ ] Document rationale
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 2**: Implement `pool_tls_prewarm()` (20 min)
|
|
|
|
|
|
- [ ] Add PREWARM_COUNTS array
|
|
|
|
|
|
- [ ] Write pre-warm function
|
|
|
|
|
|
- [ ] Add to pool_tls.h
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 3**: Integrate with init (10 min)
|
|
|
|
|
|
- [ ] Add call to hakmem.c init
|
|
|
|
|
|
- [ ] Add Makefile flag
|
|
|
|
|
|
- [ ] Update build.sh
|
2025-11-08 23:53:25 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
- [ ] **Step 4**: Build & smoke test (10 min)
|
|
|
|
|
|
- [ ] Build with pre-warm enabled
|
|
|
|
|
|
- [ ] Run dev_pool_tls.sh test
|
|
|
|
|
|
- [ ] Verify no crashes
|
2025-11-05 12:31:14 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
- [ ] **Step 5**: Benchmark (15 min)
|
|
|
|
|
|
- [ ] Run run_pool_bench.sh
|
|
|
|
|
|
- [ ] Test different sizes
|
|
|
|
|
|
- [ ] Test multi-threaded
|
2025-11-08 23:53:25 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
- [ ] **Step 6**: Measure & analyze (10 min)
|
|
|
|
|
|
- [ ] Record performance improvement
|
|
|
|
|
|
- [ ] Measure memory overhead
|
|
|
|
|
|
- [ ] Validate success criteria
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 7**: Tune (optional, 15 min)
|
|
|
|
|
|
- [ ] Adjust pre-warm counts if needed
|
|
|
|
|
|
- [ ] Re-benchmark
|
|
|
|
|
|
- [ ] Document final configuration
|
|
|
|
|
|
|
|
|
|
|
|
**Total Estimated Time**: 1.5 hours (90 minutes)
|
2025-11-08 03:18:17 +09:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
## 🎯 **Expected Outcomes**
|
|
|
|
|
|
|
|
|
|
|
|
### **Performance Targets**
|
|
|
|
|
|
```
|
|
|
|
|
|
Phase 1.5a (current): 1.79M ops/s
|
|
|
|
|
|
Phase 1.5b (target): 5-15M ops/s (+3-8x)
|
|
|
|
|
|
|
|
|
|
|
|
Conservative: 5M ops/s (+180%)
|
|
|
|
|
|
Expected: 8M ops/s (+350%)
|
|
|
|
|
|
Optimistic: 15M ops/s (+740%)
|
|
|
|
|
|
```
|
2025-11-08 23:53:25 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
### **Comparison to Phase 7**
|
|
|
|
|
|
```
|
|
|
|
|
|
Phase 7 Task 3 (Tiny):
|
|
|
|
|
|
Before: 21M → After: 59M ops/s (+181%)
|
2025-11-08 23:53:25 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
Phase 1.5b (Pool):
|
|
|
|
|
|
Before: 1.79M → After: 5-15M ops/s (+180-740%)
|
2025-11-08 03:18:17 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
Similar or better improvement expected!
|
|
|
|
|
|
```
|
2025-11-08 23:53:25 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
### **Risk Assessment**
|
|
|
|
|
|
- **Technical Risk**: LOW (proven pattern from Phase 7)
|
|
|
|
|
|
- **Stability Risk**: LOW (simple, non-invasive change)
|
|
|
|
|
|
- **Memory Risk**: LOW (1.6MB is negligible for Pool workloads)
|
|
|
|
|
|
- **Complexity Risk**: LOW (< 50 LOC change)
|
2025-11-08 03:18:17 +09:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
## 📁 **Related Documents**
|
|
|
|
|
|
|
|
|
|
|
|
- `CLAUDE.md` - Development history (Phase 1.5a documented)
|
|
|
|
|
|
- `POOL_TLS_QUICKSTART.md` - Quick start guide
|
|
|
|
|
|
- `POOL_TLS_INVESTIGATION_FINAL.md` - Phase 1.5a debugging journey
|
|
|
|
|
|
- `PHASE7_TASK3_RESULTS.md` - Pre-warm success pattern (Tiny)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 🚀 **Next Actions**
|
|
|
|
|
|
|
|
|
|
|
|
**NOW**: Start Step 1 - Design pre-warm strategy
|
|
|
|
|
|
**NEXT**: Implement pool_tls_prewarm() function
|
|
|
|
|
|
**THEN**: Build, test, benchmark
|
|
|
|
|
|
|
|
|
|
|
|
**Estimated Completion**: 1.5 hours from start
|
|
|
|
|
|
**Success Probability**: 90% (proven technique)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
2025-11-08 23:53:25 +09:00
|
|
|
|
|
2025-11-09 18:55:50 +09:00
|
|
|
|
**Status**: Ready to implement - awaiting user confirmation to proceed! 🚀
|
2025-11-11 21:49:05 +09:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## NEW 2025-11-11: Tiny L1-miss増加とUB修正(FastCache/Freeチェイン)
|
|
|
|
|
|
|
|
|
|
|
|
構造方針(確認)
|
|
|
|
|
|
- 結論: 構造はこのままでよい。`tiny_nextptr.h` に next を集約した箱構成で安全性と一貫性は確保。
|
|
|
|
|
|
- この前提で A/B とパラメータ最適化を継続し、必要時のみ“クラス限定ヘッダ”などの再設計に進む。
|
|
|
|
|
|
|
|
|
|
|
|
現象(提供値 + 再現計測)
|
|
|
|
|
|
- 平均スループット: 56.7M → 55.95M ops/s(-1.3% 誤差範囲)
|
|
|
|
|
|
- L1-dcache-miss: 335M → 501M(+49.5%)
|
|
|
|
|
|
- 当環境の `bench_random_mixed_hakmem 100000 256 42` でも L1 miss ≈ 3.7–4.0%(安定)
|
|
|
|
|
|
- mimalloc 同条件: 98–110M ops/s(大差)
|
|
|
|
|
|
|
|
|
|
|
|
根因仮説(高確度)
|
|
|
|
|
|
1) ヘッダ方式によるアラインメント崩れ(本丸)
|
|
|
|
|
|
- 1バイトヘッダで user ptr を +1 するため、stride=サイズ+1 となり多くのクラスで16B整列を失う。
|
|
|
|
|
|
- 例: 256B→257B stride で 16ブロック中15ブロックが非整列。L1 miss/μops増の主因。
|
|
|
|
|
|
2) 非整列 next の void** デリファレンス(UB)
|
|
|
|
|
|
- C0–C6 は next を base+1 に保存/参照しており、C言語的には非整列アクセスで UB。
|
|
|
|
|
|
- コンパイラ最適化の悪影響やスピル増の可能性。
|
|
|
|
|
|
|
|
|
|
|
|
対処(適用済み:UB除去の最小パッチ)
|
|
|
|
|
|
- 追加: 安全 next アクセス小箱 `core/tiny_nextptr.h:1`
|
|
|
|
|
|
- `tiny_next_off(int)`, `tiny_next_load(void*, cls)`, `tiny_next_store(void*, cls, void*)`
|
|
|
|
|
|
- memcpy ベースの実装で、非整列でも未定義動作を回避
|
|
|
|
|
|
- 適用先(ホットパス差し替え)
|
|
|
|
|
|
- `core/hakmem_tiny_fastcache.inc.h:76,108`
|
|
|
|
|
|
- `core/tiny_free_magazine.inc.h:83,94`
|
|
|
|
|
|
- `core/tiny_alloc_fast_inline.h:54` および push 側
|
|
|
|
|
|
- `core/hakmem_tiny_tls_list.h:63,76,109,115` 他(pop/push/bulk)
|
|
|
|
|
|
- `core/hakmem_tiny_bg_spill.c`(ループ分割/再接続部)
|
|
|
|
|
|
- `core/hakmem_tiny_bg_spill.h`(spill push 経路)
|
|
|
|
|
|
- `core/tiny_alloc_fast_sfc.inc.h`(pop/push)
|
|
|
|
|
|
- `core/hakmem_tiny_lifecycle.inc`(SLL/Fast 層の drain 処理)
|
|
|
|
|
|
|
|
|
|
|
|
リリースログ抑制(無害化)
|
|
|
|
|
|
- `core/superslab/superslab_inline.h:208` の `[DEBUG ss_remote_push]` を
|
|
|
|
|
|
`!HAKMEM_BUILD_RELEASE && HAKMEM_DEBUG_VERBOSE` ガード下へ
|
|
|
|
|
|
- `core/tiny_superslab_free.inc.h:36` の `[C7_FIRST_FREE]` も同様に
|
|
|
|
|
|
`!HAKMEM_BUILD_RELEASE && HAKMEM_DEBUG_VERBOSE` のみで出力
|
|
|
|
|
|
|
|
|
|
|
|
効果
|
|
|
|
|
|
- スループット/ミス率は誤差範囲(正当性の改善が中心)
|
|
|
|
|
|
- 非整列 next の UB を除去し、将来の最適化で悪化しづらい状態に整備
|
|
|
|
|
|
- mimalloc との差は依然大きく、根因は主に「整列崩れ+キャッシュ設計差」と判断
|
|
|
|
|
|
|
|
|
|
|
|
計測結果(抜粋)
|
|
|
|
|
|
- hakmem Tiny:
|
|
|
|
|
|
- `./bench_random_mixed_hakmem 100000 256 42`
|
|
|
|
|
|
- Throughput: ≈8.8–9.1M ops/s
|
|
|
|
|
|
- L1-dcache-load-misses: ≈1.50–1.60M(3.7–4.0%)
|
|
|
|
|
|
- mimalloc:
|
|
|
|
|
|
- `LD_LIBRARY_PATH=... ./bench_random_mixed_mi 100000 256 42`
|
|
|
|
|
|
- Throughput: ≈98–110M ops/s
|
|
|
|
|
|
- 固定256B(ヘッダON/OFF比較):
|
|
|
|
|
|
- `./bench_fixed_size_hakmem 100000 256 42`
|
|
|
|
|
|
- ヘッダON: ~3.86M ops/s, L1D miss ≈4.07%
|
|
|
|
|
|
- ヘッダOFF: ~4.00M ops/s, L1D miss ≈4.12%(誤差級)
|
|
|
|
|
|
|
|
|
|
|
|
新規に特定した懸念と対応案
|
|
|
|
|
|
- 整列崩れ(最有力)
|
|
|
|
|
|
- 1Bヘッダにより stride=サイズ+1 となり、16B 整列を崩すクラスが多い(例: 256→257B)。
|
|
|
|
|
|
- 単純なヘッダON/OFF比較では差は小さく、他要因との複合影響と見做し継続調査。
|
|
|
|
|
|
- UB(未定義動作)
|
|
|
|
|
|
- 非整列 void** load/store を `tiny_nextptr.h` による安全アクセサへ置換済み。
|
|
|
|
|
|
- リリースガード漏れ
|
|
|
|
|
|
- `[C7_FIRST_FREE]` / `[DEBUG ss_remote_push]` は release ビルドでは
|
|
|
|
|
|
`HAKMEM_DEBUG_VERBOSE` 未指定時に出ないよう修正済み。
|
|
|
|
|
|
|
|
|
|
|
|
成功判定(Tiny側)
|
|
|
|
|
|
- A/B(ヘッダOFF or クラス限定ヘッダ)で 256B 固定の L1 miss 低下・ops/s 改善
|
|
|
|
|
|
- mimalloc との差を段階的に圧縮(まず 2–3x 程度まで、将来的に 1.5x 以内を目標)
|
|
|
|
|
|
|
|
|
|
|
|
トラッキング(参照ファイル/行)
|
|
|
|
|
|
- 安全 next 小箱:
|
|
|
|
|
|
- `core/tiny_nextptr.h:1`
|
|
|
|
|
|
- 呼び出し側差し替え:
|
|
|
|
|
|
- `core/hakmem_tiny_fastcache.inc.h:76,108`
|
|
|
|
|
|
- `core/tiny_free_magazine.inc.h:83,94`
|
|
|
|
|
|
- `core/tiny_alloc_fast_inline.h:54` 他
|
|
|
|
|
|
- `core/hakmem_tiny_tls_list.h:63,76,109,115`
|
|
|
|
|
|
- `core/hakmem_tiny_bg_spill.c` / `core/hakmem_tiny_bg_spill.h`
|
|
|
|
|
|
- `core/tiny_alloc_fast_sfc.inc.h`
|
|
|
|
|
|
- `core/hakmem_tiny_lifecycle.inc`
|
|
|
|
|
|
- リリースログガード:
|
|
|
|
|
|
- `core/superslab/superslab_inline.h:208`
|
|
|
|
|
|
- `core/tiny_superslab_free.inc.h:36`
|
|
|
|
|
|
|
|
|
|
|
|
現象(提供値 + 再現計測)
|
|
|
|
|
|
- 平均スループット: 56.7M → 55.95M ops/s(-1.3% 誤差範囲)
|
|
|
|
|
|
- L1-dcache-miss: 335M → 501M(+49.5%)
|
|
|
|
|
|
- 当環境の `bench_random_mixed_hakmem 100000 256 42` でも L1 miss ≈ 3.7–4.0%(安定)
|
|
|
|
|
|
- mimalloc 同条件: 98–110M ops/s(大差)
|
|
|
|
|
|
|
|
|
|
|
|
根因仮説(高確度)
|
|
|
|
|
|
1) ヘッダ方式によるアラインメント崩れ(本丸)
|
|
|
|
|
|
- 1バイトヘッダで user ptr を +1 するため、stride=サイズ+1 となり多くのクラスで16B整列を失う。
|
|
|
|
|
|
- 例: 256B→257B stride で 16ブロック中15ブロックが非整列。L1 miss/μops増の主因。
|
|
|
|
|
|
2) 非整列 next の void** デリファレンス(UB)
|
|
|
|
|
|
- C0–C6 は next を base+1 に保存/参照しており、C言語的には非整列アクセスで UB。
|
|
|
|
|
|
- コンパイラ最適化の悪影響やスピル増の可能性。
|
|
|
|
|
|
|
|
|
|
|
|
対処(適用済み:UB除去の最小パッチ)
|
|
|
|
|
|
- 追加: 安全 next アクセス小箱 `core/tiny_nextptr.h:1`
|
|
|
|
|
|
- `tiny_next_load()/tiny_next_store()` を memcpy ベースで提供(非整列でもUBなし)
|
|
|
|
|
|
- 適用先(ホットパス)
|
|
|
|
|
|
- `core/hakmem_tiny_fastcache.inc.h:76,108`(tiny_fast_pop/push)
|
|
|
|
|
|
- `core/tiny_free_magazine.inc.h:83,94`(BG spill チェイン構築)
|
|
|
|
|
|
|
|
|
|
|
|
効果(短期計測)
|
|
|
|
|
|
- Throughput/L1 miss は誤差範囲で横ばい(正当性の改善が主、性能は現状維持)
|
|
|
|
|
|
- 本質は「整列崩れ」→ 次の対策で A/B 確認へ
|
|
|
|
|
|
|
|
|
|
|
|
未解決の懸念(要フォロー)
|
|
|
|
|
|
- Release ガード漏れの可能性: `[C7_FIRST_FREE]`/`[DEBUG ss_remote_push]` が release でも1回だけ出力
|
|
|
|
|
|
- 該当箇所: `core/tiny_superslab_free.inc.h:36`, `core/superslab/superslab_inline.h:208`
|
|
|
|
|
|
- Makefile上は `-DHAKMEM_BUILD_RELEASE=1`(print-flags でも確認)。TUごとのCFLAGS齟齬を監査。
|
|
|
|
|
|
|
|
|
|
|
|
次アクション(Tiny alignment 検証のA/B)
|
|
|
|
|
|
1) ヘッダ全無効 A/B(即時)
|
|
|
|
|
|
```
|
|
|
|
|
|
# A: 現行(ヘッダON)
|
|
|
|
|
|
./build.sh bench_random_mixed_hakmem
|
|
|
|
|
|
perf stat -e cycles,instructions,branches,branch-misses,cache-references,cache-misses,\
|
|
|
|
|
|
L1-dcache-loads,L1-dcache-load-misses -r 5 -- ./bench_random_mixed_hakmem 100000 256 42
|
|
|
|
|
|
|
|
|
|
|
|
# B: ヘッダOFF(クラス全体)
|
|
|
|
|
|
EXTRA_MAKEFLAGS="HEADER_CLASSIDX=0" ./build.sh bench_random_mixed_hakmem
|
|
|
|
|
|
perf stat -e cycles,instructions,branches,branch-misses,cache-references,cache-misses,\
|
|
|
|
|
|
L1-dcache-loads,L1-dcache-load-misses -r 5 -- ./bench_random_mixed_hakmem 100000 256 42
|
|
|
|
|
|
```
|
|
|
|
|
|
2) 固定サイズ 256B の比較(alignment 影響の顕在化狙い)
|
|
|
|
|
|
```
|
|
|
|
|
|
./build.sh bench_fixed_size_hakmem
|
|
|
|
|
|
perf stat -e cycles,instructions,cache-references,cache-misses,L1-dcache-loads,L1-dcache-load-misses \
|
|
|
|
|
|
-r 5 -- ./bench_fixed_size_hakmem 100000 256 42
|
|
|
|
|
|
```
|
|
|
|
|
|
3) FastCache 稼働確認(C0–C3 ヒット率の見える化)
|
|
|
|
|
|
```
|
|
|
|
|
|
HAKMEM_TINY_FAST_STATS=1 ./bench_random_mixed_hakmem 100000 256 42
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
中期対策(Box設計の指針)
|
|
|
|
|
|
- 方針A(簡易・高効果): ヘッダを小クラス(C0–C3)限定に縮小、C4–C6は整列重視(ヘッダなし)。
|
|
|
|
|
|
- 実装: まず A/B でヘッダ全OFFの効果を確認→効果大なら「クラス限定ヘッダ」へ段階導入。
|
|
|
|
|
|
- 方針B(高度): フッタ方式やビットタグ化など“アラインメント維持”の識別方式へ移行。
|
|
|
|
|
|
- 例: 16B整列を保つパディング/タグで class_idx を保持(RSS/複雑性と要トレードオフ検証)。
|
|
|
|
|
|
|
|
|
|
|
|
トラッキング(ファイル/行)
|
|
|
|
|
|
- 安全 next 小箱: `core/tiny_nextptr.h:1`
|
|
|
|
|
|
- 差し替え: `core/hakmem_tiny_fastcache.inc.h:76,108`, `core/tiny_free_magazine.inc.h:83,94`
|
|
|
|
|
|
- 追加監査対象(未修正だが next を直接触る箇所)
|
|
|
|
|
|
- `core/tiny_alloc_fast_inline.h:54,297`, `core/hakmem_tiny_tls_list.h:63,76,109,115` ほか
|
|
|
|
|
|
|
|
|
|
|
|
成功判定(Tiny)
|
|
|
|
|
|
- A/B(ヘッダOFF)で 256B 固定の L1 miss 低下、ops/s 上昇(±20–50% を期待)
|
|
|
|
|
|
- mimalloc との差が大幅に縮小(まず 2–3x → 継続改善で 1.5x 以内へ)
|
|
|
|
|
|
|
|
|
|
|
|
最新A/Bスナップショット(当環境, RandomMixed 256B)
|
|
|
|
|
|
- HEADER_CLASSIDX=1(現行): 平均 ≈ 8.16M ops/s, L1D miss ≈ 3.79%
|
|
|
|
|
|
- HEADER_CLASSIDX=0(全OFF): 平均 ≈ 9.12M ops/s, L1D miss ≈ 3.74%
|
|
|
|
|
|
- 差分: +11.7% 前後の改善(整列効果は小〜中。追加のチューニング継続)
|