在幽兰上用 KernelShark 观察 Linux 内核的 CPU 调度过程

假设在跑一个应用程序,怎么知道CPU有没有“偷懒”?不同CPU在不同的时间点做了什么?能多精确地了解?能多直观地观察?KernelShark就是一个适合回答这些问题的好工具。幽兰上已经预装好了KernelShark。

先上图,这是一个矩阵运算任务在8个CPU上的时间片分布:

这个任务在0到7号CPU上的运行情况一目了然。

想通过KernelShark得到这些分析结果,只需要如下操作:

  1. 通过root kernelshark打开KernelShark。

如果不使用root权限,从图形界面的图标直接打开也行,之后需要修改所读数据的权限。

  1. 通过Tools下的Record打开Capture页面,向Command输入要运行的程序,这里选择gematrix做矩阵乘法。然后选择好输出的数据文件trace.dat,该文件也是用于图形化分析的数据。再从Events中选择要捕获的事件,这里选择中断相关的irq和调度相关的sched。在应用之后,右侧会自动生成调用trace-cmd的命令。

  1. 等待程序运行,不同的CPU上会有各自的数据文件,最后这些数据文件会合并。注意,生成的数据trace.dat默认是root权限的,如果KernelShark不是root权限的,需要修改相应的trace.dat权限为用户权限。读取trace.dat后,分析结果如图。一眼看过去会比较乱。这时候就需要根据需求进一步筛选信息用于分析。

  1. 具体而言,可以通过filter来过滤不同的事件、CPU、任务。如果对某些CPU、某些任务、某些事件的情况感兴趣,过滤出来可以看到单独的视图。其中有明确的时间信息、任务名、PID等方便定位,也有更详细的说明信息。如果鼠标悬停在时间轴上,也会在顶部显示详细信息。搜索一下sched_switch,发现有513765次。

  1. 例如,对CPU0上发生的事情感兴趣,可以专门筛选CPU0。在时间轴的部分用鼠标划选范围还可以缩小观察范围。时间轴上方最左侧和最右侧的数字就是时间范围,可以看到在0.2ms里发生了不少的事件。

  1. 如果对某些任务的执行情况感兴趣,可以专门过滤出来观察,例如这里再进一步过滤出PID为34204的gematrix任务。

  2. 想要知道特定事件之间的时长,可以通过Marker来选中A和B两个事件,之后会自动计算出时间差。可以看到,从kworker的sched/sched_switch决定切换,到gematrix的irq/irq_handler_entry进行中断处理,时间间隔为26微秒左右。

  1. 在画图方式上,还可以通过plot画出特定任务的时间轴。这里画出idle任务和PID为34204的gematrix,可以看到,任务执行的末期,idle任务的调用时间片显著增多。

附:ubuntu安装KernelShark的注意事项

如果想在未安装KernelShark的ubuntu上安装,注意不应直接通过apt安装,因为这样安装的KernelShark无法使用Tools下的Record功能。建议根据官方在github上的指示进行编译安装。

    sudo apt-get install build-essential git cmake libjson-c-dev -y
    sudo apt-get install freeglut3-dev libxmu-dev libxi-dev -y
    sudo apt-get install flex bison -y
    sudo apt-get install fonts-freefont-ttf -y
    sudo apt-get install qtbase5-dev -y

    sudo apt-get install graphviz doxygen-gui -y

    sudo dnf install gcc gcc-c++ git cmake json-c-devel -y
    sudo dnf install freeglut-devel redhat-rpm-config -y
    sudo dnf install flex bison -y
    sudo dnf install gnu-free-sans-fonts -y
    sudo dnf install qt5-qtbase-devel -y

    sudo dnf install graphviz doxygen -y

    git clone https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/
    cd libtraceevent
    make
    sudo make install

    git clone https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/
    cd libtracefs
    make
    sudo make install

    git clone https://git.kernel.org/pub/scm/utils/trace-cmd/trace-cmd.git/
    cd trace-cmd
    make
    make libs
    sudo make install
    sudo make install_libs

    cd kernel-shark/build
    cmake ../
    make
    sudo ./install_gui.sh
作者:沈根成  创建时间:2023-03-28 18:06
最后编辑:沈根成  更新时间:2024-05-06 17:42