🌊
# 「T=16で負ける」から「mimallocに並ぶ」まで:hz3 Lane16 の一日
TL;DR
- T=16 / R=90 で mimalloc に負ける → Remote最適化へ
- Lane16 PageRemoteで改善は出たが T=2でハング
- 原因は CAS 失敗時に tail->next を上書きして循環リスト化
- 修正後、T=16 / R=90 で +9.6%、mimalloc と互角〜優位に
- さらに 3.5x退行の犯人が hot path の atomic と判明
———
1. 問題の発端
T=16 になると hz3 が mimalloc に負ける。
T=8では勝つ → T=16で負ける
→ L1キャッシュ競合・命令数増加が怪しい
結果:
- 命令数差 + キャッシュミス増
- hot path ではなく remote/owner stash が主戦場
———
2. Lane16(PageRemote)の導入
mimalloc の勝ち筋(page-local, delayed collect)を
hz3 でも“別レーン”として実装。
- hot path は維持
- boundary は 2箇所だけ
- HZ3_LANE_T16_R90_PAGE_REMOTE で opt-in
———
3. T=2でハング発生
原因: CAS 失敗時に tail->next を毎回上書き → リストが壊れる
修正前(バグ)
do {
hz3_obj_set_next(tail, old_head); // 毎回上書き
} while (!CAS(...));
修正後
void* old_head = atomic_load(...);
for (;;) {
hz3_obj_set_next(tail, old_head);
if (CAS_strong(...)) break;
}
→ T>1のハングが解消
———
4. 性能改善(A/B)
T=16 / R=90 / RUNS=5
Baseline: 69.5M
Lane16: 76.1M
改善: +9.6%
さらに warmup + taskset で再計測すると
mimallocと互角〜+5〜7%優位まで到達。
———
5. “別の大問題”が判明
論文時点(e165faccc)は hz3 234M
HEADでは 65M(3.5x退行)
原因は hot path の atomic_fetch_add:
static _Atomic uint32_t g_hz3_malloc_first = 0;
if (atomic_fetch_add_explicit(&g_hz3_malloc_first, 1, ...) == 0) { ... }
→ 毎回 atomic RMW が発生していた
対処
- HZ3_MALLOC_FIRST_LOG を導入(デフォルト OFF)
- hot path から atomic を除去
———
Discussion