Skip to content

debug: add in-kernel scheduler, pipe and heap benchmarks - #110

Open
JiTianYu391 wants to merge 2 commits into
ViudiraTech:developfrom
JiTianYu391:codex/debug-kbench
Open

JiTianYu391 wants to merge 2 commits into
ViudiraTech:developfrom
JiTianYu391:codex/debug-kbench

Conversation

@JiTianYu391

Copy link
Copy Markdown
Contributor

当前缺少能同时暴露耗时、CPU 放置和调度计数的内核内微基准,容易把迁移、IPI 或崩溃混入性能结论。新增仅由 kbench[=rounds] 命令行启用的工作线程,启动等待 3 秒后测试 yield/sleep、等待队列、pipe、malloc/free 和 kthread 生命周期。

每行输出 worker 起止 CPU/迁移次数和 steal/migr/ipi/cs/wake 计数增量;测试覆盖同核、跨核和多组并发。pipe 新增四个小型内部 API 以便直接测试环形缓冲,无需模拟进程 fd 表。未加 kbench 参数时不注册线程。

复现:构建内核,在 Limine 命令行添加 console=ttyS0 kbench=3,以 -smp 5 引导并收集 kbench: 串口行。切记:kthread 绑定修复尚未合并时,请检查 CPU/迁移字段,不能把请求的 same-cpu 当作实际放置。

本轮基线输出示例 数字
malloc/64/solo 115.4 ns/op
malloc/64/all-cpus 2130.3 ns/op
10 次启动,每次 3 轮 均输出 done

本 PR 是测量工具,不声称工具本身带来性能提升。原始提交中没有临时锁争用探针;本轮临时 heap 完整性检查也未纳入提交。

验证环境:5 vCPU、KVM、2 GiB、每次 QEMU 超时 60 秒。所有独立分支直接从 origin/develop@153578b5 开出,目标均为 develop;每个分支均独立完成 GCC 16.2 / LTO 构建,构建源只取 git ls-files '*.c',切分支后清除对应 .o/.d。按已知基线问题临时关闭 CONFIG_VIRTIO_GPU。除 strcpy PR 自身外,独立构建在链接命令临时加 -Wl,-u,strcpy,绕过原始 develop 的已复现 LTO 缺陷;没有把其他 PR 的源码带进分支。

运行基准时明确使用独立 sched 修复、strcpy 修复、kbench 和 kthread 绑定的共同测试覆盖层,以免把已知调度崩溃或实际 CPU 不符误算成待测修改的效果。覆盖层仅用于测试镜像,不构成提交依赖。

已否决方案:把偷取限制为源 rq 至少两个任务,曾使 ping-pong 约 3 µs 恶化到 7.8 µs;轮询 idle 无明显收益。这些改动均未采用。宿主负载高,仅把交替多次中位数中超过 20% 的差异视为性能结论。

🤖 Generated with ClaudeCode

JiTianYu391 and others added 2 commits October 21, 2026 06:36
Booting with kbench[=rounds] on the command line starts a kernel worker
that waits three seconds for boot to settle and then prints one line
per benchmark:

  scheduler   sched_yield() alone and between two threads, and
              task_sleep_ticks(1) latency
  wait queues ping-pong round trips on one CPU, across CPUs, and with
              every CPU pair running at once
  pipes       1-byte ping-pong and 4 KiB / 64 KiB streaming, same CPU,
              cross CPU and in parallel
  heap        malloc()+free() of 64 B, 4 KiB and 64 KiB alone and on
              every CPU at once, plus a 256-object batch
  kthreads    create + run + exit of a trivial kernel thread

Each line also reports where every worker started and ended, how often
it migrated, and the scheduler counter deltas summed over all
runqueues (newidle steals, migrations, reschedule IPIs, context
switches, wakeups), so a result can be explained rather than just
compared.

The pipe benchmarks need to drive a ring without a file descriptor
table, so pipe.c gains a small in-kernel API: pipe_kernel_create(),
pipe_kernel_read(), pipe_kernel_write() and pipe_kernel_destroy().

Without the option nothing is registered and boot is unchanged.

Reproduction and output: boot a 5-vCPU KVM guest with kbench=3. The
pre-optimization baseline reports roughly 115 ns for malloc(64) alone
and 2,100 ns with all five workers, exposing the shared slab/page locks.
No performance improvement is claimed for this instrumentation PR.

Validation: standalone origin/develop build with CONFIG_VIRTIO_GPU off;
use -Wl,-u,strcpy to work around the pre-existing baseline LTO defect.
Stress measurements use the independent scheduler race and pinned-thread
fixes as explicitly recorded test overlays, not branch dependencies.
The worker CPU/migration fields expose placement changes even without
the binding fix. No temporary contention probes are included.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
clang-tidy flagged the widening multiplication used as a pointer offset
and the unparenthesised 2 * p + 1 in kb_pair_cpus(). Fill the table
through a cursor instead.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
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.

1 participant