207 lines
6.0 KiB
Markdown
207 lines
6.0 KiB
Markdown
|
|
# Phase PERF-ULTRA-REFILL-OPT-1 計画:C7 ULTRA refill パス最適化
|
|||
|
|
|
|||
|
|
## 背景
|
|||
|
|
|
|||
|
|
### 現状分析 (PERF-ULTRA-REBASE-4)
|
|||
|
|
|
|||
|
|
Mixed 16-1024B ワークロード(iters=10M, ws=8192)のホットパス分析結果:
|
|||
|
|
|
|||
|
|
| 関数 | self% | 最適化状況 |
|
|||
|
|
|------|-------|--------|
|
|||
|
|
| free (dispatcher) | 25.48% | ✅ snapshot 済み(ENV/route 初期化時のみ) |
|
|||
|
|
| malloc (dispatcher) | 21.13% | ✅ LUT 化済み(size_to_class/route 両方 0 calls) |
|
|||
|
|
| tiny_c7_ultra_alloc | 7.66% | ⚠️ 既に最適化済み(直線化限界)|
|
|||
|
|
| tiny_c7_ultra_free | 3.50% | ✅ TLS push + segment learning |
|
|||
|
|
| so_free | 2.47% | ❌ v3 backend(最適化機会未調査) |
|
|||
|
|
| so_alloc_fast | 2.39% | ❌ v3 backend(最適化機会未調査) |
|
|||
|
|
| **tiny_c7_ultra_page_of** | **1.78%** | **🎯 refill path(最適化ターゲット)** |
|
|||
|
|
| so_alloc | 1.21% | - |
|
|||
|
|
| classify_ptr | 1.15% | - |
|
|||
|
|
|
|||
|
|
### 重要な発見
|
|||
|
|
|
|||
|
|
1. **Dispatcher/Gate レベルの最適化は既に完了**
|
|||
|
|
- free dispatcher (25%) = malloc/free の C API コール + routing overhead
|
|||
|
|
- malloc dispatcher (21%) = 内部的には LUT/ULTRA で最適化済み
|
|||
|
|
- これ以上削減するには architecture レベルの再設計が必要
|
|||
|
|
|
|||
|
|
2. **次のボトルネックは C7 ULTRA 内部**
|
|||
|
|
- alloc (7.66%) + free (3.50%) + refill (1.78%) = **12.94%**
|
|||
|
|
- このうち refill (1.78%) が新規ボトルネック
|
|||
|
|
|
|||
|
|
3. **Refill パスが visible に**
|
|||
|
|
- C7 ULTRA は page を「必要に応じて allocate」
|
|||
|
|
- refill 呼び出しが所々で発生し、tiny_c7_ultra_page_of が呼ばれている
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 目的
|
|||
|
|
|
|||
|
|
**C7 ULTRA refill パスを最適化し、tiny_c7_ultra_page_of の 1.78% を削減**
|
|||
|
|
|
|||
|
|
期待効果:
|
|||
|
|
- refill path 削減で 0.5-1% の削減
|
|||
|
|
- 全体スループット +0.5-2M ops/s(30M → 30.5-32M ops/s)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 現状の C7 ULTRA refill 構造
|
|||
|
|
|
|||
|
|
### TLS キャッシュ管理
|
|||
|
|
|
|||
|
|
C7 ULTRA は以下の構造を持つ:
|
|||
|
|
```c
|
|||
|
|
typedef struct TinyC7UltraBox {
|
|||
|
|
// TLS freelist(alloc pop 用)
|
|||
|
|
void* freelist[128];
|
|||
|
|
uint16_t count;
|
|||
|
|
|
|||
|
|
// Segment 情報(free で学習)
|
|||
|
|
uintptr_t seg_base, seg_end;
|
|||
|
|
tiny_c7_ultra_segment_t* cached_segment;
|
|||
|
|
|
|||
|
|
} TinyC7UltraBox;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Refill のトリガー
|
|||
|
|
|
|||
|
|
1. **Alloc 側**:
|
|||
|
|
- TLS freelist が empty → refill_cold パスへ
|
|||
|
|
- segment から新しいページを割り当て
|
|||
|
|
- 128 個のブロックを freelist に詰める
|
|||
|
|
|
|||
|
|
2. **Retire 側**:
|
|||
|
|
- freelist が full → retire_cold へ
|
|||
|
|
- ページを segment に返す
|
|||
|
|
|
|||
|
|
### tiny_c7_ultra_page_of の役割
|
|||
|
|
|
|||
|
|
refill/retire 時に「ページを特定するため」に呼ばれる:
|
|||
|
|
```c
|
|||
|
|
tiny_c7_ultra_page_meta_t* tiny_c7_ultra_page_of(void* p,
|
|||
|
|
tiny_c7_ultra_segment_t** out_seg,
|
|||
|
|
uint32_t* out_page_idx) {
|
|||
|
|
tiny_c7_ultra_segment_t* seg = tiny_c7_ultra_segment_from_ptr(p);
|
|||
|
|
if (!seg) return NULL;
|
|||
|
|
|
|||
|
|
// Offset 計算と page index 取得
|
|||
|
|
uintptr_t offset = (uintptr_t)p - (uintptr_t)seg->base;
|
|||
|
|
uint32_t idx = (uint32_t)(offset / seg->page_size);
|
|||
|
|
|
|||
|
|
// Bounds check
|
|||
|
|
if (idx >= seg->num_pages) return NULL;
|
|||
|
|
|
|||
|
|
return &seg->pages[idx];
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**cost breakdown**:
|
|||
|
|
- tiny_c7_ultra_segment_from_ptr(): O(1) ptr lookup
|
|||
|
|
- offset 計算: 固定コスト(1-2 cycles)
|
|||
|
|
- page_size division: 可変(seg->page_size がキャッシュマイス可能)
|
|||
|
|
- bounds check: 1-2 cycles
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 最適化候補
|
|||
|
|
|
|||
|
|
### Option 1: Page size を固定に(最大効果)
|
|||
|
|
|
|||
|
|
**現状**:
|
|||
|
|
```c
|
|||
|
|
size_t page_size; // seg ごとに異なる可能性
|
|||
|
|
uint32_t idx = (uint32_t)(offset / seg->page_size); // division
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**問題**: `seg->page_size` が毎回参照 → cache line miss 可能性
|
|||
|
|
|
|||
|
|
**最適化案**:
|
|||
|
|
- TINY_C7_ULTRA_PAGE_SIZE を macro 定義(64KiB 固定と仮定)
|
|||
|
|
- division → right shift に最適化(`offset >> PAGE_SHIFT`)
|
|||
|
|
|
|||
|
|
**期待**: division 命令削減で 0.1-0.2% 削減
|
|||
|
|
|
|||
|
|
**条件**: C7 ULTRA segment の page_size が常に一定であることを確認
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Option 2: Segment learning を alloc 側に移動(中程度効果)
|
|||
|
|
|
|||
|
|
**現状**:
|
|||
|
|
- free 時に segment を学習(initial miss)
|
|||
|
|
- その後 free はキャッシュされた seg_base/seg_end でチェック
|
|||
|
|
|
|||
|
|
**提案**:
|
|||
|
|
- alloc refill 時に segment を学習/cache
|
|||
|
|
- refill が segment を既に知っている → segment_from_ptr が不要に
|
|||
|
|
|
|||
|
|
**期待**: refill パスで segment_from_ptr call 削減 → 0.2-0.3%
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Option 3: Page lookup の TLS cache(小程度効果)
|
|||
|
|
|
|||
|
|
**提案**:
|
|||
|
|
- 直前に lookup した page を TLS に cache
|
|||
|
|
- 同じページに対する refill 呼び출しなら cache hit
|
|||
|
|
|
|||
|
|
**期待**: 0.1% 程度(alloc batch が小さいため)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 実装計画(推奨順)
|
|||
|
|
|
|||
|
|
### Phase REFILL-OPT-1a: Page Size Macro 化
|
|||
|
|
|
|||
|
|
1. **確認**:
|
|||
|
|
- C7 ULTRA segment の page_size 値を記録
|
|||
|
|
- 常に 64KiB(または固定値)か確認
|
|||
|
|
|
|||
|
|
2. **実装**:
|
|||
|
|
- TINY_C7_ULTRA_PAGE_SIZE macro を定義
|
|||
|
|
- tiny_c7_ultra_page_of で `offset >> TINY_C7_ULTRA_PAGE_SHIFT` に変更
|
|||
|
|
- tiny_c7_ultra_segment_t から page_size を削除(optional)
|
|||
|
|
|
|||
|
|
3. **テスト**:
|
|||
|
|
- Mixed bench: 29.5-32M ops/s 範囲で確認
|
|||
|
|
- SEGV/assert なし
|
|||
|
|
|
|||
|
|
4. **計測**:
|
|||
|
|
- perf で tiny_c7_ultra_page_of self% が 1.78% → 1.5% 以下か確認
|
|||
|
|
|
|||
|
|
### Phase REFILL-OPT-1b: Segment Learning in Alloc
|
|||
|
|
|
|||
|
|
1. **実装**:
|
|||
|
|
- tiny_c7_ultra_alloc_refill で segment を学習して cache
|
|||
|
|
- tiny_c7_ultra_segment_from_ptr 呼び出し削減
|
|||
|
|
|
|||
|
|
2. **テスト同様**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## リスク評価
|
|||
|
|
|
|||
|
|
| リスク | 確率 | 対策 |
|
|||
|
|
|--------|------|------|
|
|||
|
|
| page_size が可変 | 低 | 確認 phase で判定、fallback 用 code keep |
|
|||
|
|
| segment cache miss | 低 | TLS cache 容量確保 |
|
|||
|
|
| allocation pattern 変化 | 低 | multi-thread test で確認 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 成功条件
|
|||
|
|
|
|||
|
|
- ✅ Build 成功、warning なし
|
|||
|
|
- ✅ Mixed bench で SEGV/assert なし
|
|||
|
|
- ✅ Throughput 回帰なし(≥ −2%)
|
|||
|
|
- ✅ tiny_c7_ultra_page_of self% が 1.5% 以下
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 参考資料
|
|||
|
|
|
|||
|
|
- `PERF_ULTRA_REBASE_4.md`: 詳細計測結果
|
|||
|
|
- `TINY_C7_ULTRA_DESIGN.md`: C7 ULTRA 設計概要
|
|||
|
|
- `docs/analysis/ALLOC_GATE_ANALYSIS.md`: Gate 分析
|
|||
|
|
|