You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取带时间戳的Linux CPU调度事件?进程调度统计方案咨询

解决方案:计算进程就绪到调度的时长及期间调度进程数

一、现成工具推荐

  • perf:Linux原生性能分析工具,可精准追踪调度事件。执行perf record -e sched:sched_wakeup,sched:sched_switch记录目标场景的调度数据,再用perf script解析输出,通过关联目标进程的sched_wakeup(进入就绪态)和sched_switch(被CPU调度)事件时间戳,计算就绪延迟;同时统计期间sched_switch事件中其他进程的调度次数。
  • ftrace:内核内置追踪框架,安全且性能开销可控。用trace-cmd record -e sched_wakeup -e sched_switch采集事件,停止后执行trace-cmd report筛选目标进程的事件流,手动或通过脚本计算时间差,统计期间其他进程的调度次数。
  • bpftrace:基于eBPF的动态追踪工具,无需修改内核,性能影响极小。可编写极简脚本直接输出所需指标:
    #!/usr/bin/bpftrace
    
    BEGIN {
      printf("PID\t唤醒时间(ns)\t调度时间(ns)\t就绪延迟(ns)\t期间调度其他进程数\n");
    }
    
    tracepoint:sched:sched_wakeup {
      if (args->pid == $1) {
        @wakeup[args->pid] = nsecs;
        @count[args->pid] = 0;
      }
    }
    
    tracepoint:sched:sched_switch {
      if (@wakeup[$1] && args->next_pid != $1) {
        @count[$1]++;
      }
      if (args->next_pid == $1 && @wakeup[$1]) {
        $latency = nsecs - @wakeup[$1];
        printf("%d\t%d\t%d\t%d\t%d\n", $1, @wakeup[$1], nsecs, $latency, @count[$1]);
        delete(@wakeup[$1]);
        delete(@count[$1]);
      }
    }
    
    运行时指定目标PID:bpftrace script.bt <目标进程PID>,直接得到计算结果。

二、直接修改内核的问题分析

你之前用printk修改内核出现性能问题甚至死锁,核心原因:

  • 调度路径属于内核临界区,printk会尝试获取控制台锁,容易与调度逻辑持有的内核锁形成锁竞争,触发死锁。
  • 高频printk会产生大量日志输出,占用CPU和IO资源,严重拖慢系统性能。

三、自定义开发的替代方案(不推荐)

若现成工具无法满足需求,优先选择eBPF程序替代直接修改内核:

  • eBPF程序运行在内核态但有安全隔离机制,不会破坏内核稳定性,性能开销远低于硬编码printk。
  • 通过eBPF追踪点或kprobe捕获sched_wakeup和sched_switch事件,在用户态处理数据并计算指标,无需修改内核源码。

内容的提问来源于stack exchange,提问作者Senith Uthsara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 16:23:17