无人车实时优化-Linux实时优化的一些小概念
-
date_range 21/03/2019 info
我们都知道对于机器人应用来说实时性很重要, 以及Linux不是一个实时系统, 但是说:
- 实时性到底对我的程序有什么影响?
- 默认情况下, Linux的实时性怎么样?
- rt-linux 有什么用?
所以这里简单的做个实验, 来直观的认识一下.
注: 下面的测试数据, 都是在CPU满载的情况下得出.
1. 调度实时
1.1. 测试程序
一个简单ROS程序逻辑如下: 以100hz向外发送数据.
while (1) {
nanosleep(10000000);
process();
}
我们接下来就用这个程序的循环周期间隔
来评估这个程序的实时性.
PS: Robotics上常见的高频率基本也就集中在200hz~100hz, 比如说IMU传感器的周期和各种控制的采样周期
注: usleep受限制于jiffes, 精度10ms
1.2. 实时调度器
默认Linux的调度器为CFS.
在CFS调度器下, ROS应用跑了5分钟, 其中出现的最大延迟为50ms
[ INFO] [1551423662.755795004]: dt: now 10893.000000 max 54892.000000
下面我们设置这个应用为rt调度策略
chrt --rr -p <priority between 1-99> pid
注: 优先级最好大于50, 不受中断影响
跑了5分钟, 其中出现的最大延迟为13ms
[ INFO] [1551425162.716713135]: dt: now 10447.000000 max 13020.000000
1.2.1. 结论
可以看到, 在默认cfs调度器的情况, 一个程序的周期运行时间在CPU高负载的情况下是得不到保障的.
对关键的程序来说设置rt调度非常有必要.
不然叠加起来, 就有可能出现数百毫秒的延迟.
如果这是一个刹车链路, 那在80km/h的速度下刹车距离就会上下浮动10几米,
1.3. RT-Linux
在上面rt调度的情况, 可以看到最大的周期间隔13ms, 而不是严格的10ms.
造成这个3ms的原因有很多, 包括内核不支持抢占等等.
而RT-Linux补丁, 就是为了解决这些原因而产生的.
这里下载补丁, 重新编译内核
https://cdn.kernel.org/pub/linux/kernel/projects/rt/3.14/older/
上车继续执行测试程序(rt调度)
跑了5分钟, 其中出现的最大延迟为10.7ms
[ INFO] [1551434073.434294415]: dt: now 10284.000000 max 10701.000000
1.3.1. 结论
RT-Linux补丁可以解决默认Linux下毫秒级的调度误差
1.4. 其他
2. 程序执行实时
上文研究循环周期间隔
所针对的都是调度
上的实时性.
对实时性而言, 像process时间
也要考虑起来, 这针对的是程序执行
上的实时性.
一些影响程序实时性的点:
- 内存缺页
- Linux applications access memory by using virtual addresses. Each virtual address translates into a physical address with the help of hardware that uses translation tables. This feature makes it possible to address more virtual memory than there is physical memory available, assuming that not all applications need all their allocated memory at the same time.
- I/O阻塞
- 多线程同步阻塞
- 其他……
这里不再详细描述, 有兴趣可看以下参考:
- http://linuxrealtime.org/index.php/Designing_Real-Time_Applications
- https://index.ros.org/doc/ros2/Tutorials/Real-Time-Programming/
- https://wiki.linuxfoundation.org/realtime/documentation/howto/applications/application_base
3. 总结
上文两者都做到确定后, 就可以计算任务的deadline
.
4. 附录
4.1. 相关数据
4.1. Tips
以下两条命令, 可以看程序主动/被动施放cpu的次数.
sar -w 1 3
pidstat -w