Phase PERF-ULTRA-FREE-OPT-1: C4-C7 ULTRA free 薄型化
- C4-C7 ULTRA free を pure TLS push + cold segment learning に統一 - C7 ULTRA free を同じパターンに整列(likely/unlikely + FREE_PATH_STAT_INC) - C4/C5/C6 ULTRA は既に最適化済み(統一 legacy fallback 経由) - base/user 変換を tiny_ptr_convert_box.h マクロで統一 実測値 (Mixed 16-1024B, 1M iter, ws=400): - Baseline (C7 のみ): 42.0M ops/s, legacy=266,943 (49.2%) - Optimized (C4-C7): 46.5M ops/s, legacy=26,025 (4.8%) - 改善: +9.3% (+4M ops/s) FREE_PATH_STATS: - C6 ULTRA: 137,319 free + 137,241 alloc (100% カバー) - C5 ULTRA: 68,871 free + 68,827 alloc (100% カバー) - C4 ULTRA: 34,727 free + 34,696 alloc (100% カバー) - Legacy: 266,943 → 26,025 (−90.2%, C2/C3 のみ) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -657,58 +657,40 @@ alloc 側に TLS pop を追加して統合し、完全な alloc/free サイク
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Phase PERF-ULTRA-ALLOC-OPT-1 実装完了 (2025-12-11 改訂版)
|
## Phase PERF-ULTRA-ALLOC-OPT-1 実装完了 (2025-12-11)
|
||||||
|
|
||||||
### 方針転換: C7 ULTRA は独立サブシステムとして tiny_c7_ultra.c 内部最適化に統一
|
C7 ULTRA alloc は tiny_c7_ultra.c 内最適化で self%/throughput ともほぼ不変。
|
||||||
|
これ以上は refill/path 設計が絡むため一旦打ち止め。
|
||||||
|
|
||||||
**設計判断**:
|
---
|
||||||
- 寄生型の C7 ULTRA_FREE_BOX は設計的に不整合と判断し削除
|
|
||||||
- C7 ULTRA は C4/C5/C6 ULTRA と異なり、専用 segment + TLS を持つ独立サブシステム
|
|
||||||
- 寄生型パターンは他の ULTRA クラスには適用可能だが、C7 には不適合
|
|
||||||
- **C7 は tiny_c7_ultra.c 内部だけで最適化する方針**
|
|
||||||
|
|
||||||
### 実装内容
|
## Phase PERF-ULTRA-FREE-OPT-1 実装完了 (2025-12-11)
|
||||||
|
|
||||||
**1. 寄生型パスの削除**:
|
**実装内容**:
|
||||||
- `core/box/tiny_c7_ultra_free_box.{h,c}` を削除
|
- C4–C7 ULTRA free を pure TLS push + cold segment learning に統一
|
||||||
- `core/box/tiny_c7_ultra_free_env_box.h` を削除
|
- C4/C5/C6 ULTRA は既に最適化済み(統一 legacy fallback 経由)
|
||||||
- Makefile から `tiny_c7_ultra_free_box.o` を削除
|
- C7 ULTRA free を同じパターンに整列(likely/unlikely + FREE_PATH_STAT_INC 追加)
|
||||||
- `malloc_tiny_fast.h` を元の `tiny_c7_ultra_alloc()` / `tiny_c7_ultra_free()` 呼び出しに戻す
|
- base/user 変換は tiny_ptr_convert_box.h マクロで統一済み
|
||||||
|
|
||||||
**2. TLS 構造の最適化** (`tiny_c7_ultra_box.h`):
|
**実測値** (Mixed 16-1024B, 1M iter, ws=400):
|
||||||
- count を struct の先頭に移動 (L1 cache locality 向上)
|
- Baseline (C7 ULTRA のみ): 42.0-42.1M ops/s, legacy_fb=266,943 (49.2%)
|
||||||
- 配列ベース TLS キャッシュに変更 (capacity=128, C6 と同じ)
|
- Optimized (C4-C7 ULTRA 全有効): 45.7-47.0M ops/s, legacy_fb=26,025 (4.8%)
|
||||||
- freelist: linked-list → BASE pointer 配列に変更
|
- **改善: +8.8-11.7%** (平均 +9.3%, 約 +4M ops/s)
|
||||||
- cold フィールド (seg_base/seg_end/segment meta) を後方に配置
|
|
||||||
|
|
||||||
**3. alloc の純 TLS pop 化** (`tiny_c7_ultra.c`):
|
**FREE_PATH_STATS 分析**:
|
||||||
- hot path: 1 分岐のみ (count > 0)
|
- C7 ULTRA: 275,057 (50.7%, 不変)
|
||||||
- TLS access は 1 回のみ (ctx に cache)
|
- C6 ULTRA: 0 → 137,319 free + 137,241 alloc (**100% カバー**, legacy C6 完全排除)
|
||||||
- ENV check を呼び出し側 (malloc_tiny_fast.h) に移動
|
- C5 ULTRA: 0 → 68,871 free + 68,827 alloc (**100% カバー**, legacy C5 完全排除)
|
||||||
- segment/page_meta アクセスは refill 時 (cold path) のみ
|
- C4 ULTRA: 0 → 34,727 free + 34,696 alloc (**100% カバー**, legacy C4 完全排除)
|
||||||
|
- Legacy fallback: 266,943 → 26,025 (**-90.2%**, C2/C3 のみ残存)
|
||||||
|
|
||||||
**4. free の UF-3 segment learning 維持**:
|
**C4/C5/C6-heavy 安定性確認**:
|
||||||
- 最初の free で segment 学習 (seg_base/seg_end を TLS に記憶)
|
- C4-heavy (65-128B): 55.0M ops/s, SEGV/assert なし
|
||||||
- 以降は seg_base/seg_end 範囲チェック → TLS push
|
- C5-heavy (129-256B): 56.5M ops/s, SEGV/assert なし
|
||||||
- 範囲外は v3 free にフォールバック
|
- C6-heavy (257-768B): 16.9M ops/s, SEGV/assert なし
|
||||||
|
|
||||||
### 実測値 (Mixed 16-1024B, 1M iter, ws=400)
|
**評価**: **目標達成**
|
||||||
|
- Legacy 49% → 5% に削減(−90%)
|
||||||
**Perf profile (self%)**:
|
- C4/C5/C6 ULTRA により Mixed throughput +9.3%
|
||||||
- `tiny_c7_ultra_alloc`: **7.66%** (維持 - 既に最適化済み)
|
- 全クラス(C4-C7)で統一された TLS push パターン確立
|
||||||
- `tiny_c7_ultra_free`: **3.50%**
|
|
||||||
- Throughput: **43.5M ops/s** (1M iterations)
|
|
||||||
|
|
||||||
**評価**: **部分達成**
|
|
||||||
- 寄生型パターンの撤回による設計一貫性の回復: **成功**
|
|
||||||
- Array-based TLS cache への移行: **成功**
|
|
||||||
- pure TLS pop パターンへの統一: **成功**
|
|
||||||
- perf self% 削減 (7.66% → 5-6%): **未達成** (既に最適)
|
|
||||||
|
|
||||||
**次のアクション**:
|
|
||||||
1. refill path の最適化 (segment 取得の軽量化)
|
|
||||||
2. page_meta 管理の簡略化 (bitmap 化など)
|
|
||||||
3. C4-C7 ULTRA free 群 (5.41%) の最適化に移行
|
|
||||||
|
|
||||||
詳細は `docs/analysis/TINY_C7_ULTRA_DESIGN.md` を参照。
|
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,12 @@
|
|||||||
#include "tiny_region_id.h"
|
#include "tiny_region_id.h"
|
||||||
#include "box/tiny_c7_ultra_segment_box.h"
|
#include "box/tiny_c7_ultra_segment_box.h"
|
||||||
#include "box/tiny_front_v3_env_box.h"
|
#include "box/tiny_front_v3_env_box.h"
|
||||||
|
#include "box/free_path_stats_box.h"
|
||||||
|
|
||||||
|
#ifndef likely
|
||||||
|
#define likely(x) __builtin_expect(!!(x), 1)
|
||||||
|
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
// TLS context
|
// TLS context
|
||||||
static __thread tiny_c7_ultra_tls_t g_tiny_c7_ultra_tls = {0};
|
static __thread tiny_c7_ultra_tls_t g_tiny_c7_ultra_tls = {0};
|
||||||
@ -164,29 +170,27 @@ void tiny_c7_ultra_free(void* ptr) {
|
|||||||
tiny_c7_ultra_tls_t* tls = &g_tiny_c7_ultra_tls;
|
tiny_c7_ultra_tls_t* tls = &g_tiny_c7_ultra_tls;
|
||||||
void* base = (uint8_t*)ptr - 1; // Convert USER -> BASE pointer
|
void* base = (uint8_t*)ptr - 1; // Convert USER -> BASE pointer
|
||||||
|
|
||||||
// Segment learning (cold path on first free)
|
// 1) Initial segment learning (cold path, once per thread)
|
||||||
if (tls->seg_base == 0) {
|
if (unlikely(tls->seg_base == 0)) {
|
||||||
tiny_c7_ultra_segment_t* seg = tiny_c7_ultra_segment_from_ptr(ptr);
|
tiny_c7_ultra_segment_t* seg = tiny_c7_ultra_segment_from_ptr(ptr);
|
||||||
if (!seg) {
|
if (seg != NULL) {
|
||||||
so_free(7, ptr); // Not from ULTRA segment
|
tls->seg = seg;
|
||||||
return;
|
tls->seg_base = (uintptr_t)seg->base;
|
||||||
|
tls->seg_end = tls->seg_base + ((size_t)seg->num_pages * seg->page_size);
|
||||||
}
|
}
|
||||||
tls->seg = seg;
|
|
||||||
tls->seg_base = (uintptr_t)seg->base;
|
|
||||||
tls->seg_end = tls->seg_base + ((size_t)seg->num_pages * seg->page_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hot path: range check + TLS push
|
// 2) Fast path: range check + TLS push
|
||||||
uintptr_t addr = (uintptr_t)base;
|
uintptr_t addr = (uintptr_t)base;
|
||||||
if (__builtin_expect(addr >= tls->seg_base && addr < tls->seg_end, 1)) {
|
if (likely(tls->seg_base != 0 &&
|
||||||
// Within segment: push to TLS cache
|
addr >= tls->seg_base &&
|
||||||
if (__builtin_expect(tls->count < TINY_C7_ULTRA_CAP, 1)) {
|
addr < tls->seg_end &&
|
||||||
tls->freelist[tls->count++] = base;
|
tls->count < TINY_C7_ULTRA_CAP)) {
|
||||||
return;
|
tls->freelist[tls->count++] = base;
|
||||||
}
|
FREE_PATH_STAT_INC(c7_ultra_fast);
|
||||||
// Cache full: fall through to v3
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to v3 (out of segment or cache full)
|
// 3) Slow path: fallback to v3 (out of segment or cache full)
|
||||||
so_free(7, ptr);
|
so_free(7, ptr);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -170,3 +170,21 @@ perf self% は baseline と同等。これは元の linked-list 実装も既に
|
|||||||
1. refill path の最適化(segment 取得の軽量化)
|
1. refill path の最適化(segment 取得の軽量化)
|
||||||
2. page_meta 管理の簡略化(bitmap 化など)
|
2. page_meta 管理の簡略化(bitmap 化など)
|
||||||
3. C4-C7 ULTRA free 群(5.41%)の最適化に移行
|
3. C4-C7 ULTRA free 群(5.41%)の最適化に移行
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 設計整理: C7 独立 vs C4/C5/C6 寄生
|
||||||
|
|
||||||
|
**C7 ULTRA**: 独立サブシステム(tiny_c7_ultra.c に閉じた segment + TLS)
|
||||||
|
- 専用の segment 管理(2MiB Segment / 64KiB Page)
|
||||||
|
- 独自の TLS context(freelist + page_meta + segment pointers)
|
||||||
|
- alloc/free/refill が全て tiny_c7_ultra.c 内で完結
|
||||||
|
- 既存 allocator(v1/v3/pool)には依存しない(fallback 時を除く)
|
||||||
|
|
||||||
|
**C4/C5/C6 ULTRA**: 寄生型(既存 allocator 上の TLS cache)
|
||||||
|
- 専用 segment は持たない
|
||||||
|
- 既存 allocator(v1/v3/pool)に「寄生」して TLS キャッシュだけ追加
|
||||||
|
- free 時に TLS push、alloc 時に TLS pop(キャッシュミス時は既存 allocator へ fallback)
|
||||||
|
- minimal overhead で既存パスに統合可能
|
||||||
|
|
||||||
|
次フェーズ(PERF-ULTRA-FREE-OPT-1)では、これら ULTRA の free 側(TLS push パス)を統一された形に薄くする。
|
||||||
|
|||||||
Reference in New Issue
Block a user