Linux实时任务优化方法

Posted 从善若水

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux实时任务优化方法相关的知识,希望对你有一定的参考价值。

本人就职于国际知名终端厂商,负责modem芯片研发。
在5G早期负责终端数据业务层、核心网相关的开发工作,目前牵头6G算力网络技术标准研究。

Linux实时任务优化方法

本人目前在国内知名终端厂商从事5G/6G新特性验证工作,因验证平台对实时性要求较高,所以对如何提升任务实时性上做了一些学习,总结成下面的博文与大家分享

本文涉及的缩写:
UT: unit test
CAS:compare and swap

优化分为平台侧优化和软件侧优化

👉软件侧优化:
     ①设置线程CPU亲和性(affinity)
     ②使用线程池技术,将一些耗时但对实时性要求不高的流程/运算剥离出来,从架构上优化实时性能
     ③使用内存池/大页内存技术,解决Page fault带来的巨大延时问题
     ④使用SIMD指令,提升运算速度
     ⑤线程资源共享尽量采用内存共享的方式(UT时应检查是否发生Cache的伪共享)
     ⑥尽量使用自旋锁或者CAS之类的无锁数据结构保证数据的访问安全
     ⑦日志功能也是损失实时性的一方面,使用时需要多加注意
     ⑧设置线程调度算法为实时调度算法(SCHED_FIFO、SCHED_RR、SCHED_DEALINE)

👉平台侧优化(重点介绍这部分):
     ①隔离实时应用所在的CPU,使其不在操作系统调度算法的调度范围内
     ②开启内核Feature “NO_HZ_FULL”,降低Timer中断对应用的影响
     ③设置实时应用所在CPU的中断亲和性

隔离CPU

隔离CPU使其不在操作系统任务调度范围内,减少内核/用户线程以及外设中断对实时应用的影响

设置isolcpus参数隔离指定cpu

我们的测试环境有4个cpu,所以我们编写如下的测试code

#include<unistd.h>
int main()
{
	fork();
	fork();
	while(1);
}

top查看cpu状态

现在我们修改grub文件,隔离id=2的cpu:

在/etc/default/grub中的下面一行添加最后的isolcpus参数
    GRUB_CMDLINE_LINUX_DEFAULT=“quiet splash isolcpus=2”(cpu序号从0开始)
    也可以添加到:
    GRUB_CMDLINE_LINUX=“isolcpus=2”

sudo update-grub
    检查/boot/grub/grub.cfg时间戳,查看更新是否成功,如果没有成功 传送门

重启操作系统

查看 /proc/cmdline里是不是有isolcpu参数,有的话说明本次重启确实带了这个参数

再次运行测试程序,查看CPU状态,发现CPU2空闲

此时可以通过taskset或者pthread_setaffinity_np函数将程序绑定到CPU2,实现独占一个CPU。

注意:隔离CPU之后,操作系统同样不会将内核线程放到这个CPU上运行,除非调用类似kthread_bind_mask()函数将内核线程绑定到隔离的CPU上;同样外设中断也不会绑定到这个CPU,除非设置了中断亲和性


降低Timer中断影响

编译内核

登录kernel.org下载需要的内核版本
执行下述命令

sudo apt update && sudo apt upgrade
sudo apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison

解压内核文件

tar -zxf linux-5.3.10.tar.xz
cd linux-5.3.10

设置内核参数

make menuconfig


编译内核

make -j4

安装内核

sudo make modules_install #首先安装模块
sudo make install #安装内核

启用内核作为引导

sudo update-initramfs -c -k 5.12.2 #5.3.10是我下载的内核版本号

修改grub开启启动显示界面并更新grub

sudo vi /etc/default/grub

sudo update-grub

设置NO_HZ_FULL参数

CPU2没有开启NO_HZ_FULL之前我们看到Timer tick是一直在增加的

修改grub参数(修改方法同上)
    GRUB_CMDLINE_LINUX_DEFAULT=“quiet splash isolcpus=2 nohz_full=2”(cpu序号从0开始)
也可以添加到:
    GRUB_CMDLINE_LINUX=“isolcpus=2 nohz_full=2”

再次查看CPU2的Timer tick,在没有任务/只有一个任务的情况下,timer tick几乎没有增加


以上是关于Linux实时任务优化方法的主要内容,如果未能解决你的问题,请参考以下文章

用于自动驾驶的实时 YUV 多任务 CNN

在linux中如何根据nice值设置任务时间片

YUV-MultiNet用于自动驾驶的实时YUV多任务CNN

YUV-MultiNet用于自动驾驶的实时YUV多任务CNN

linux学习:Nginx--常见功能配置片段与优化-06

Android 逆向整体加固脱壳 ( DEX 优化流程分析 | DexPrepare.cpp 中 dvmOptimizeDexFile() 方法分析 | /bin/dexopt 源码分析 )(代码片段