0%

Linux内核多线程计算

Linux内核文档

  • 链接

    内核时间获取

    jiffiesjiffies_64

  • 参考链接
  • 实际上计算的是电脑开机到现在总共的时钟中断次数。取决于系统的频率,单位是Hz,可能是100或者额000之类的,可以自己修改,因此精度不高
    • 具体位置在linux/param.h->asm/param.h->asm-generic/param.h->uapi/asm-generic/param.hCONFIG_HZ中,HZ参考链接 如图
    • picture 5
    • 这个CONFIG_HZ定义在picture 6 中,值是250如图
    • picture 7
  • 使用#include <linux/jiffies.h>中的jiffies变量直接获取,该变量的定义为
    extern unsigned long volatile __cacheline_aligned_in_smp __jiffy_arch_data jiffies;
  • 将这个变量转化为时间的形式有很多函数,见jiffies.h中,比如
    extern unsigned int jiffies_to_msecs(const unsigned long j);
    extern unsigned int jiffies_to_usecs(const unsigned long j);
  • 其中的参数直接传入jiffies即可(或者jiffies_64get_jiffies_64()也可以,效果类似)
    • 但是似乎并不精确
    • picture 4

结果

  • picture 1
    • 可见并不是直接等于内核时间,而是与内核时间之间有一个稳定的差值,大概在300s左右,暂时不清楚原因

      使用rdts统计经过的CPU周期

  • 使用rdtsc()
  • 包含asm/msr.h头文件(需要正确配置VSCode的应用目录具有/usr/src/linux-headers-<uname -r的输出>/arch/x86/include/,否则将会搜索出错误的头文件
  • 参考链接1

    使用ktime实现高精度计时

  • 头文件# include <linux/timekeeping.h>或者#include <linux/ktime.h>
  • 函数ktime_get_ns()等函数族,有不同的精度和单位
  • 使用ktime_get_ns()/1000000得到的微秒级时间是精确的
    • picture 8
  • 使用ktime_get_ns()/1000%1000000,后面的取模是防止溢出

    结果

  • 使用ktime_get_ns()%1000000直接得到纳秒级别的结果
    • picture 9
  • 参考链接

使用多个文件时候的编译

  • 参考
  • 当对应的模块需要多个源文件时,可以添加多个.o文件作为依赖,比如
    obj-m := kThOut.o

    kThOut-objs := kTh.o task.o

    CURRENT_PATH := $(shell pwd)
    LINUX_KERNEL := $(shell uname -r)
    LINUX_KERNEL_PATH := /usr/src/linux-headers-$(LINUX_KERNEL)


    all:
    make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
    clean:
    make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean

  • 注意代码中不要有两个模块具有同样的名字,比如一个依赖项是kTh,即使这个模块包含了主要的函数比如module_init等,也不能这么做,输出模块必须单独取一个名字比如kThOut,否则输出的文件加载到内核后会出现kTh: module license 'unspecified' taints kernel.之类的报错
  • 上述代码中需要编译的模块名字是kThOut,因此添加一行
    <模块名>-objs := <c源文件1>.o <c源文件2>.o ...
  • 注意,内核线程的返回类型必须是int

    结果

  • 向量长度为100000时
  • picture 2
  • 可能是内核线程创建的代价较大导致的
  • 将结果输出可以发现几乎是按照线程创建的顺序计算的
    • picture 10
    • 可以看到内核线程单个的计算时间比主线程两层循环的时间还长,目前原因未知

代码仓库

  • 仓库

    git提交脚本

    #!/bin/bash 
    git add .
    git add *
    echo "请输入commit信息:"
    read info
    # 字符串非空判断等
    if [[ -n "$info" ]]
    then
    # echo "正在commit: $info"
    git commit -m "$info"
    echo "正在push: $info"
    git push origin master
    else
    echo "使用非法, 未输入commit参数!"
    fi
  • 检测字符串是否是空的if [[ -n "$info" ]]