Linux打入实时性补丁对比测试
验证实时内核
实时内核的应用场景
总结
前言
Linux 内核实时补丁(Real-Time Patch,通常称为-RT或RT补丁)是一项旨在为 Linux 内核提供实时性能的补丁。它通过降低内核延迟、提高可预测性和响应速度,使得 Linux 系统能够满足对时间敏感的应用需求,如工业控制、音频处理、机器人技术等。
本篇环境
硬件平台:飞凌开发板
内核源码:5.10.66-rt53
编译环境: 20.04 LTS
编译工具链:-linux-gnu-
实时内核主要特性
低延迟:RT 补丁使得内核能够更快速地响应外部事件,减少了系统响应时间和处理延迟。
高优先级调度:为实时任务提供了更高的优先级调度,确保关键任务能够在预期的时间内完成。
抢占支持:通过增强内核的抢占能力,允许实时任务在任何时刻打断其他任务,尤其是长时间运行的内核代码。
锁的优化:对内核锁的使用做了优化,减少了锁竞争和临界区的时间。
更好的线程处理:针对实时线程的调度策略进行了改进,以更好地支持高优先级任务。
补丁做了哪些事情
高分辨率定时器:减少精度误差,精确纳秒级延时。
中断线程化:采用内核线程执行中断处理函数,实时任务不会被中断抢占
自旋锁改为实时互斥锁:自旋锁保护的临界区是不可抢占的,导致实时进程不能被及时调度,实时内核使用实时互斥锁实现自旋锁,临界区是可以抢占的,所以可以实现优先级继承,避免优先级反转问题,从而更适合实时应用。
补充下优先级继承和优先级反转的概念
什么是优先级反转问题
假设进程1的优先级低,进程2的优先级高。进程1持有互斥锁,进程2申请互斥锁,因为进程1已经占有互斥锁,所以进程2必须睡眠等待,导致优先级高的进程2等待优先级低的进程1,如果进程2是实时进程,就会影响进程2的实时性
如果存在进程3,优先级在进程1和进程2之间,那么情况更糟糕。假设进程1仍然持有互斥锁,进程2正在等待。进程3开始运行,因为它的优先级比进程1高,所以它可以抢占进程1,导致进程1持有互斥锁的时间延长,进程2等待的时间延长
什么是优先级继承
优先级继承可以解决优先级反转问题。如果低优先级的进程持有互斥锁,高优先级的进程申请互斥锁,那么把持有互斥锁的进程的优先级临时提升到申请互斥锁的进程的优先级。在上面的例子中,把进程1的优先级临时提升到进程2的优先级,防止进程3抢占进程1,使进程1尽快执行完临界区,减少进程2的等待时间。
实时互斥锁()实现了优先级继承。锁的等待者按优先级从高到低排序,如果优先级相等,那么先申请锁的进程的优先级高。持有锁的进程,如果它的优先级比优先级最高的等待者低,那么把它的优先级临时提升到优先级最高的等待者的优先级
安装和使用实时补丁
要使用实时补丁,您通常需要:
下载内核源代码:获取您希望补丁的内核版本的源代码。
wget https://www.kernel.org/pub/linux/kernel/vX.Y/linux-X.Y.Z.tar.xz
下载 RT 补丁:从官方的 RT 补丁网站下载与您内核版本匹配的补丁。
RT 补丁通常可以在找到
应用补丁:
tar -xf linux-X.Y.Z.tar.xz
cd linux-X.Y.Z
patch -p1 < /path/to/patch-rt-X.Y.Z.patch
配置内核:
在内核源代码目录中运行以下命令,以配置内核选项:
make menuconfig
在配置菜单中,您可以启用实时选项。确保启用了 Model选项,并选择适当的实时选项。
编译和烧录内核:
编译内核
make
烧录内核
./upgrade_tool di -b boot.img
重启系统:重启系统以使用新的内核。
验证实时内核
您可以使用uname命令检查当前运行的内核版本:
uname -r
如果内核是实时内核,版本号中通常会包含-rt后缀。
测试
是Linux上非常流行、常见的实时性测试工具,它通过使用高精度定时器来测量两个时间点的延时.
安装下
git clone git://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git
cd rt-tests
git checkout stable/v1.0
make all
make install
我们先在不打补丁版本上用工具验证下三种场景:空载跑,满载跑压力,Wi-Fi 打流,然后再打实时补丁版本上再用工具再验证下这三种场景。
不打实时内核补丁空载跑效果
首先将每个CPU的设置为
echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu4/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu5/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu6/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu7/cpufreq/scaling_governor
然后用工具测实时性
cyclictest -l 1000000 -m -Sp99 --policy=fifo -h 25000 -q >output-kong-nort
参数说明:
总的来说:就是创建一个具有高优先级(99)和 FIFO 策略的实时线程,循环执行 1,000,000 次,每次执行之间的间隔为 25 毫秒,并将结果写入文件-kong-nort。
然后用.sh脚本生成结果统计图
#!/bin/bash
# 1. Run cyclictest
# 2. Get maximum latency
max=`grep "Max Latencies" output | tr " ""\n" | sort -n | tail -1 | sed s/^0*//`
# 3. Grep data lines, remove empty lines and create a common field separator
grep -v -e "^#" -e "^$" output | tr " ""\t" >histogram
# 4. Set the number of cores, for example这里我设置的4核
cores=4
# 5. Create two-column data sets with latency classes and frequency values for each core, for example
for i in `seq 1 $cores`
do
column=`expr $i + 1`
cut -f1,$column histogram >histogram$i
done
# 6. Create plot command header
echo -n -e "set title \"Latency plot\"\n\
set terminal png\n\
set xlabel \"Latency (us), max $max us\"\n\
set logscale y\n\
set xrange [0:400]\n\
set yrange [0.8:*]\n\
set ylabel \"Number of latency samples\"\n\
set output \"plot.png\"\n\
plot " >plotcmd
# 7. Append plot command data references
for i in `seq 1 $cores`
do
iftest$i != 1
then
echo -n ", " >>plotcmd
fi
cpuno=`expr $i - 1`
iftest$cpuno -lt 10
then
title=" CPU$cpuno"
else
title="CPU$cpuno"
fi
echo -n "\"histogram$i\" using 1:2 title \"$title\" with histeps" >>plotcmd
done
# 8. Execute plot command
gnuplot -persist
执行./.sh -kong-nort会在同目录下生成plot.png
打开plot.png文件如下图所示
不打实时内核补丁满载跑CPU压力效果
首先将每个CPU的设置为
echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu4/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu5/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu6/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu7/cpufreq/scaling_governor
跑压力测试可以用也可以是-ng,个人推荐用-ng,因为前者需要简单快速的压力测试并且不需要复杂的设置,是一个不错的选择。后者需要更高的灵活性、更多的测试选项和更复杂的测试场景,-ng将是更好的选择。使用-ng前要安装下
sudo apt-get install stress-ng
安装后跑下压力测试
stress-ng -c 8 --cpu-method fft --timerfd-freq 1000000 -t 24h &
参数说明:
-ng: 表示您正在使用-ng工具,这是一个用于压力测试的强大工具。
-c 8: 这个选项指定要使用的 CPU 负载线程的数量。在此示例中,8表示将启动 8 个线程来施加 CPU 负载。一般来说,您应该根据系统的 CPU 核心数来选择合适的线程数量,以充分利用系统资源。
--cpu- fft: 这个参数指定使用的 CPU 负载测试方法。fft代表快速傅里叶变换(Fast ),这是一种计算密集型的算法,适合用于 CPU 压力测试。
---freq : 此选项设置定时器的频率,以纳秒为单位。纳秒等于 1 毫秒,这个参数调整了负载任务的调度频率,使其更频繁地进行计算。
-t 24h: 这个选项设置压力测试的持续时间。在该示例中,24h表示测试将持续 24 小时。
总的来说就是执行一个为期 24 小时的 CPU 压力测试,使用 8 个线程并采用快速傅里叶变换方法。
后台可以看到每个CPU都跑满了
接下来可以用工具测实时性
cyclictest -l 1000000 -m -Sp99 --policy=fifo -h 25000 -q >output-cpu-nort
总的来说:就是创建一个具有高优先级(99)和 FIFO 策略的实时线程,循环执行 1,000,000 次,每次执行之间的间隔为 25 毫秒,并将结果写入文件-cpu-nort
执行./.sh -cpu-nort会在同目录下生成plot.png
打开plot.png文件如下图所示
打实时内核补丁空载跑效果
首先将每个CPU的设置为
echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu4/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu5/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu6/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu7/cpufreq/scaling_governor
然后用工具测实时性
cyclictest -l 1000000 -m -Sp99 --policy=fifo -h 25000 -q >output-kong-nort
总的来说:就是创建一个具有高优先级(99)和 FIFO 策略的实时线程,循环执行 1,000,000 次,每次执行之间的间隔为 25 毫秒,并将结果写入文件-kong-nort。
然后用.sh脚本生成结果统计图 ,执行./.sh -kong-nort会在同目录下生成plot.png
打实时内核补丁满载跑CPU压力效果
先跑下压力测试
stress-ng -c 8 --cpu-method fft --timerfd-freq 1000000 -t 24h &
总的来说就是执行一个为期 24 小时的 CPU 压力测试,使用 8 个线程并采用快速傅里叶变换方法。
后台可以看到每个CPU都跑满了
然后在运行工具测实时性
cyclictest -l 1000000 -m -Sp99 --policy=fifo -h 25000 -q >output-cpu-nort
总的来说:就是创建一个具有高优先级(99)和 FIFO 策略的实时线程,循环执行 1,000,000 次,每次执行之间的间隔为 25 毫秒,并将结果写入文件-cpu-nort
执行./.sh -cpu-nort会在同目录下生成plot.png
打开plot.png文件如下图所示
结果会发现不管是空载跑还是CPU压力跑满载都是打完实时内核补丁的版本测试出来的最大时延比没打实时内核补丁会更低。大家还可以试下Wi-Fi打流时TX,RX最大时延效果
实时内核的应用场景
实时内核非常适合以下场景:
工业自动化:用于控制和监测工业设备,确保快速响应时间。
音频处理:用于实时音频处理和数字信号处理(DSP),减少音频延迟。
机器人技术:在机器人系统中确保对于传感器和执行器的快速响应。
网络通信:在对时间敏感的网络应用中,确保低延迟数据包处理。
不过随着半导体的不断进步,现在多核异构的AMP芯片诞生,主流方案也有跑Linux和RTOS双系统,强实时性任务放在RTOS的核上跑,非实时性任务放Linux核上跑。像,等芯片方案
总结
本文学习到了在Linux系统如何保证实时性,如果有疑问的话可以在评论区留言,对本篇文章学废的同学,可以一键三连!
文章转自公众号[Linux随笔录]
参考博文:
end