Skip to content

feat: 64 分片 uint64_t 位掩码、O(1) 热点 box 缓存与 SWAR 快路径 - #13

Merged
miaobyte merged 2 commits into
array2d:mainfrom
carsontung666:feat/slotsboxobj-v3
Oct 19, 2026
Merged

miaobyte merged 2 commits into
array2d:mainfrom
carsontung666:feat/slotsboxobj-v3

Conversation

@carsontung666

@carsontung666 carsontung666 commented Oct 17, 2026 •

Copy link
Copy Markdown
Collaborator

本 PR 将 slotsboxobj 升级至 v3:底层树节点由 v2 的 uint8_t[8] 逐位扫描重构为 64-ary uint64_t bitmask(配合单段连续 clzll/ctzll O(1) 快路径与 6 步无分支 SWAR),并引入最高 64 个独立 shard、per-shard O(1) active box cache(alloc/free 直接绕过树下探)以及空子树按需回收机制。相比 main(v2),单线程吞吐提升 4.8x–761x(混合负载 20.33 Mops/s),16 线程吞吐提升 136x–331x(混合负载 248.46 Mops/s),并将多线程竞争下的假性分配失败率从 95% 降至 0%。


改动概览

  1. 64-shard + uint64_t bitmask

    • free_mask / child_mask 改为 uint64_t(64-ary tree,节点 480B,8B 对齐,移除 packed)。
    • 单段连续 free mask 走 clzll/ctzll O(1) 快路径;碎片 mask 走 6 步无分支 SWAR 计算 sbo_mask_contmax 与 sbo_mask_find_run。
    • 按 data_size 与 head_size 动态切分 1..64(2 的幂)个独立 shard;sbo_alloc 先 trylock 轮询再阻塞加锁,消除多线程竞争下的假 OOM。
    • initial-exec TLS 记录线程 home shard(含 pid 校验防 fork 冲突、步长 9 错开相邻线程 cache line、连续 4 次 miss 才迁移 home 防追逐抖动)。
  2. Hot-path 优化

    • Per-shard O(1) active box cache:复用 sbo_lock_t 的 64B cache line padding 存储 L1/L2/L3 的 hot_id1 与 hot_base,sbo_alloc / sbo_free / sbo_allocated_size 命中时直接 O(1) 定位目标 box,省去 root -> L2 -> L1 逐层下探。
    • Cache-line 布局与惰性初始化:sbo_box_t 中 states[64] 紧邻 32B header(位于前 1.5 条 cache line);sbo_box_format 省去 child_cap/children 的 384B memset(由 child_mask 门控);sbo_free_obj_slots 仅写单字节 states[start] = SBO_FREE。
    • Lazy subtree reclaim (sbo_reclaim_empty):常规 churn 保留空叶 box 避免反复分配/释放抖动;当父层满或 pool_meta 块不足时按需通过 blocks_free 回收空子树并合并回父 slot。
  3. Bug 修复

    • sbo_find_obj_node:校验 level >= 2 对象的低位偏移对齐((unit & ((1ULL << sh) - 1)) == 0),修复内部 8B 对齐偏移(如 off + 8)误匹配父 slot 导致误 free / sbo_allocated_size 返回非 0 的问题。
    • sbo_init:在 sbo_magic_ok(meta) 前校验 head_size <= sizeof(sbo_meta_t) + SBO_POOL_HDR,修复极小 buffer 下的 ASan heap-buffer-overflow。
    • sbo_combined / sbo_propagate:max_obj_cap 截断至 SBO_MULT_MAX (63),并在 comb == p_old 时提前终止向上传播,修复空 box 虚报 level + 1 容量及 64 <-> 63 传播风暴。
    • sbo_find_alloc:多层下钻前预检 pool_meta 剩余 block 数并在深层 blocks_alloc OOM 时回滚已分配的中间 box。
    • tutorial/03_stress.c:DATA_SIZE 改为合法的 8 * 64^3 (2MB),修复 ctest 失败。

Before / After 性能对比

测试环境:gcc 13.2 -O3 -DNDEBUG,taskset -c 0-15,DATA_SIZE = 128MB,META_SIZE = 16MB,200k ops/thread,5 次运行取中位数。

Workload Threads Before: v2 (main) v3 Initial (faafafe) After: v3 Optimized vs. v2 vs. v3 Initial
Mixed {8,64,512,4096}B 1T 3.27 Mops/s (0% fail) 16.93 Mops/s (0% fail) 20.33 Mops/s (0% fail) 6.2x +20.1%
Mixed {8,64,512,4096}B 4T 1.62 Mops/s (91.7% fail) 64.09 Mops/s (0% fail) 80.31 Mops/s (0% fail) 49.6x +25.3%
Mixed {8,64,512,4096}B 8T 0.85 Mops/s (95.0% fail) 119.53 Mops/s (0% fail) 162.55 Mops/s (0% fail) 191x +36.0%
Mixed {8,64,512,4096}B 16T 0.75 Mops/s (95.0% fail) 180.64 Mops/s (0% fail) 248.46 Mops/s (0% fail) 331x +37.5%
Small {8..64}B 1T 3.11 Mops/s (0% fail) 16.01 Mops/s (0% fail) 20.42 Mops/s (0% fail) 6.6x +27.5%
Small {8..64}B 16T 0.75 Mops/s (95.2% fail) 205.00 Mops/s (0% fail) 227.36 Mops/s (0% fail) 303x +10.9%
Churn (2048 live, 8B..64KB) 1T 2.73 Mops/s (0% fail) 12.24 Mops/s (0% fail) 13.06 Mops/s (0% fail) 4.8x +6.7%
Churn (2048 live, 8B..64KB) 16T 0.83 Mops/s (90.9% fail) 74.41 Mops/s (0% fail) 112.74 Mops/s (0% fail) 136x +51.5%
Alloc-only (50k fill) 1T 0.02 Mops/s (0% fail) 14.86 Mops/s (0% fail) 15.22 Mops/s (0% fail) 761x +2.4%

验证

检查项 Before (main) v3 Initial (faafafe) After (Current)
ctest (make test, 10 项) 9/10 (03_stress fail) 9/10 (03_stress fail) 10/10 PASS
tutorial/test.py (01–17) 17/17 PASS 17/17 PASS 17/17 PASS
18_model_check (16T x 100k + 边界/合并回归) N/A 内部偏移 & 空子树合并失败 PASS
ASan + UBSan sbo_init 越界读 sbo_init 越界读 0 errors
TSan (16T 并发压测) 0 races 0 races 0 races
下游 kvspace (01/05/06) PASS PASS PASS

@carsontung666 carsontung666 changed the title v3: 64 shard + uint64 free_mask feat(v3): 64-shard radix-64 allocator with O(1) hot-box cache & SWAR bitmasks Oct 17, 2026
@carsontung666 carsontung666 changed the title feat(v3): 64-shard radix-64 allocator with O(1) hot-box cache & SWAR bitmasks feat(v3): 64-shard uint64_t bitmask, O(1) hot-box cache & SWAR fast paths Oct 17, 2026
@carsontung666 carsontung666 changed the title feat(v3): 64-shard uint64_t bitmask, O(1) hot-box cache & SWAR fast paths feat(v3): 64 分片 uint64_t 位掩码、O(1) 热点 box 缓存与 SWAR 快路径 Oct 17, 2026
@carsontung666 carsontung666 changed the title feat(v3): 64 分片 uint64_t 位掩码、O(1) 热点 box 缓存与 SWAR 快路径 feat: 64 分片 uint64_t 位掩码、O(1) 热点 box 缓存与 SWAR 快路径 Oct 17, 2026
@miaobyte

Copy link
Copy Markdown
Contributor

感谢贡献。当前分支与 main 存在冲突,且分支基线较旧(基于 5f6dff2,落后 main 29 个提交),合并前需要处理:

冲突文件

  • include/slotsboxmalloc/slotsboxobj.h
  • tutorial/03_stress.c
  • tutorial/CMakeLists.txt

请 rebase 到最新 main 并解决上述冲突。注意 rebase 时保留 main 已有的 header-only 构建方式(src/slotsboxmalloc.c 中的 BLOCKMALLOC_IMPLEMENTATION,CMake 不链接 blockmalloc 的 .so)。

另外两点请一并跟进:

  1. 本 PR 当前没有 CI checks 运行,rebase 后请确认 CI 已触发并通过。
  2. v3 的头文件内部结构变更会让下游 kvspace-c 编译失败(其直接使用 sbo_meta_t.head_size/slot_bytes/sizeof_block_head、sbo_box_t.slots/box_boundary/obj_boundary/free_bitmap/child_max_cap、SBO_BITMAP_B 等),发布前需要同步适配下游或提供稳定的内部布局接口。

rebase 完成后欢迎再 ping 验证。

meta magic 升到 slotsboxobj64v3,和 v2 不兼容。公开 API 不变。
附 18_model_check 和 doc/perf-v3.md。
@miaobyte
miaobyte merged commit 7305d2a into array2d:main Oct 19, 2026
4 checks passed
@carsontung666

Copy link
Copy Markdown
Collaborator Author

感谢合并与发布 v0.1.7!下游 kvspace-c 对 v0.1.7 (v3) 的同步升级与在线扩容适配 PR 已提交并通过全部 CI / ctest 验证:array2d/kvspace-c#47

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants