找回密码
 -注册-
查看: 9312|回复: 62
打印 上一主题 下一主题

Linux音频系统中的延迟优化实践,兼谈preempt rt和augomagic preemption

[复制链接]
跳转到指定楼层
1
发表于 2023-11-4 01:34 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式 来自 荷兰
经常看到有烧友说hifi要降低延迟。很多动手能力强的烧友用上了daphile、snakeoil os、audiolinux/gentooplayer等的rt内核,用上了hqplayer os的低延迟内核,甚至是xenomai内核。有的烧友强化路由器和交换机的性能,获得更低的网络延迟。还有些公司使用带有特别低延迟控制单元的soc,如Bricasti M5/M21用了TI的pru。本帖首先简单介绍这些降低延迟的方案和音频回放的关系,之后介绍我实践的Linux音频系统低延迟优化方案。

1. 什么是延迟,为什么要rt
2. 硬件因素
3. 内核补丁
4. 内核设置
5. 软件设置
6. 小结

来自 11楼
发表于 2023-11-4 10:21 | 只看该作者 来自 上海宝山区
延迟测试对比

1 低延迟内核
gentoo-rpi4 /usr/src # cyclictest  -l 10000 -m -Sp98 -i100 -d0                                                                                             
# /dev/cpu_dma_latency set to 0us                                                                                                                           
policy: fifo: loadavg: 0.08 0.33 0.17 2/108 7829                                                                                                            

T: 0 ( 7826) P:98 I:100 C:  10000 Min:      8 Act:    9 Avg:    9 Max:      60                                                                              
T: 1 ( 7827) P:98 I:100 C:   9936 Min:      8 Act:    9 Avg:    9 Max:      16                                                                              
T: 2 ( 7828) P:98 I:100 C:   9823 Min:      7 Act:    9 Avg:    8 Max:      14                                                                              
T: 3 ( 7829) P:98 I:100 C:   9691 Min:      9 Act:    9 Avg:    9 Max:      30



2 automagic内核 (做了内核隔离,所以只有三cpu的测试结果)
GentooRed /usr/src/linux # cyclictest  -l 10000 -m -Sp98 -i100 -d0                                                                                          
WARN: stat /dev/cpu_dma_latency failed: No such file or directory                                                                                          
policy: fifo: loadavg: 0.97 0.43 0.16 1/124 25456                                                                                                           

T: 0 (25454) P:98 I:100 C:  10000 Min:      4 Act:    4 Avg:    4 Max:      26                                                                              
T: 1 (25455) P:98 I:100 C:   9942 Min:      4 Act:    5 Avg:    5 Max:      61                                                                              
T: 2 (25456) P:98 I:100 C:   9839 Min:      4 Act:    5 Avg:    4 Max:      27


回复

使用道具 举报

来自 39楼
 楼主| 发表于 2023-12-16 20:58 | 只看该作者 来自 北京
本帖最后由 中关村东路 于 2023-12-16 21:36 编辑

补充三组数据,图1是我树莓派4(cm)上的,延迟2/3/2/22;图2是audiolinux在树莓派5下超频到2800的数据2/3/2/10(多组数据取最优);图3是m1p的数据,作为一台普通或者高性能电脑的数据,比优化过的延迟差距是很大的。这么看的话,

1. 树莓派5可能未必是一个好的选择了,一方面性能可能提升有限,另一方面引入南桥芯片管理包括usb、网卡等等在内的“低速设备”


2. 当然了,如图2 audiolinux的说法,他的树莓派4b延迟是树莓派5的4-5倍,那就是8/12/8/40……如果用我的配置,树莓派5可能也会是个不错的选择


3. 最终用哪个还是要靠听感的,优化延迟就是随便玩玩


图1,我的配置下树莓派4(cm)延迟测试,2/3/2/22


图2,audiolinux树莓派5延迟测试,2/3/2/10



图3,看看正常数据是什么样的,apple silicon来被吊打



回复

使用道具 举报

2
 楼主| 发表于 2023-11-4 01:35 | 只看该作者 来自 荷兰
1. 什么是延迟,为什么要rt

我们把上述例子中的延迟分为三类:一类是网络延迟,顾名思义不详细解释了;一类是回放系统,如网桥中的cpu latency,也就是播放指令从ALSA驱动发出,到任务提交给了解码器的这个小周期;第三类是控制精度或latency,指的是对自己控制指令发放时间和实际时间的误差限,比如我问系统几点了,他告诉我一个时间,在windows上的误差大约是十几毫秒,而在xenomai和TI pru上数量级是10us。

这些延迟的例子中,网络延迟在玩游戏放视频中对体验影响很大,但其实一般认为对音频回放质量几乎没有影响,举个和我没有商业利益关系的某数播的例子(真没有),很多人说他家的数播软件做的很好,我没听过但知道大致原理,他播放音乐前要把所有数据缓冲进内存,转换了格式再播放,而并不会因为我或早或迟点击开始按钮,或者数据缓冲了多久而改变音质。网络延迟别到了延误的地步就够。

各类rt内核,低延迟内核,xenomai内核以及Bricasti等使用的TI pru单元等硬件是控制latency的例子。这在机器人控制等方面是极其重要的指标,因为机器人控制算法几乎都是闭环控制(close-loop),也就是算法中当前时间的控制量是当前时间、以及当前时间可观测到的系统状态的函数,但在音乐流式回放这种开环结构中影响并不大。

有人说你不是说好了三类延迟吗,怎么两类就把所有例子都用完了,cpu延迟呢。控制精度的提升,总是和cpu延迟的降低分不开的。但很遗憾的是,其中只有hqplayer os使用的低延迟内核和preempt rt内核两类是通用方案,只需在Linux系统中把你的播放进程设为特定类别即可获得控制精度提升,和CPU延迟降低。而xenomai的软件实现、和TI pru的硬件实现都需要播放器和DAC遵循特定API——这就导致了PPT中xenomai超低的延迟和本站烧友lalekuku实测的巨大背离;类似的用了TI pru的Bricasti网桥能卖上万,使用同样方案的beaglebone black开发板巨烂无比的性能和回放效果——除非是硬件软件厂商自己遵循相关API开发自己的产品,否则用户在自己的自行车上安装劳斯莱斯的发动机是不会提高性能的。而常见的Roon/HQPlayer/MPD等等播放软件全都是面相通用硬件设计的,无法天然的享受这些API带来的低延迟。

CPU延迟优化到底能带来什么听感提升呢,像我在本站的所有帖子一样,不在讨论范畴之内。这里无责任引用Holo的说法:“所谓的延时低就好声音的说法,是基于射频噪声在时序上和音乐产生紧耦合后,降低对听感的影响”。好吧,其实我根本不知道他说的什么意思。本文接下来的章节介绍我所使用的降低延迟的方案,可能有些在之前的帖子里说过,为了保证完整性就再简单说一次小标题,具体命令可以看我别的帖子。需要说明,虽然其中一部分篇幅是网络延迟相关的,但却是以降低CPU延迟为首要目标,并非为了优化网络延迟本身。


回复

使用道具 举报

3
 楼主| 发表于 2023-11-4 01:35 | 只看该作者 来自 荷兰
2. 硬件因素

这段本来是不想写的,但对硬件设备还没稳定下来的烧友可能有些价值。

2.1 第一条非CPU性能莫属。很尴尬吧,高性能CPU会带来更低的延迟,更流畅的软件体验,也可能引入干扰,同时供电和散热也不好处理。事实上有一些高端(贵)方案会搞Intel至强CPU或者AMD标压CPU。如果你能搞定干扰、供电和散热,上高性能CPU是有收益的。我就知道有高端烧友用的几万块的jcat线性ATX电源和标压CPU做网桥。我自己是低烧,目前用四核赛扬加PCIE-usb卡做naa,树莓派4b/cm4做roon客户端听着玩。AMD 5600x+nvidia rtx 4090做HQ。十代i3加96G内存缓存组zfs raid做roon core。几个网桥全部无风扇+线电。其他机器是开关电源+风扇自动启停。目前硬件的钱还集中在耳机解码耳放上。

2.2 除非性能有硬性要求,否则尽量使用单芯片设计的CPU。举个例子amd 7900x这种胶水的高端CPU,反而延迟高于7600x,这就至少并不适合作为网桥CPU了。

2.3 在绝大部分场景,关闭超线程(HT/SMT)能降低延迟。只有程序质量较低,系统负载较高的情况下适合打开超线程。

2.4 打开turbo boost,pbo,或者超频会降低延迟,当然,一些朋友包括我希望保持cpu主频固定且无风扇,就无法利用这项提升了。

2.5 选择尽量新的CPU。这条也是很无奈,很多老CPU bug多,打开mitigation会大幅降低性能,并提高延迟。同样在内核中不打补丁的情况下,老CPU风险却比新CPU大得多。


回复

使用道具 举报

4
 楼主| 发表于 2023-11-4 01:35 | 只看该作者 来自 荷兰
3. 内核补丁

正好最近Linux内核主线升级到6.6分支,很大可能会是一个长期服务的LTS分支,我也把zfs NAS之外的其他系统都升级到了6.6。下面列的一些上游补丁还没升级的,暂时由我在我的Gentoo软件源维护。除非你也用Gentoo,否则你阅读本文时上游已经更新的代码建议直接使用原始链接,因为我水平有限,且肯定没在你的发行版上测试过。

3.1 rt patch

著名的rt patch【1】,具体的代码可在链接【2】下载。需要指出的是,kernel 6.6对应的rt patch在经典的Full Preempt基础上提出了改进:Automagic preemption mode with runtime tweaking support。经典的full preempt模式缺点——闲时系统负载较高,数据吞吐量较低——在新模式下都有改进。具体介绍可以在链接【2】中阅读。

非常有价值的是,经典full preempt模式下树莓派cm4 soc直出的dwc2 usb一直有bug,播放高码率DSD/PCM时会有卡顿,新模式解决了这个问题。略有遗憾,官方推出的rt patch【1,2】目前只支持x86系统下的automagic模式,也就是说树莓派的armhf和arm64都是不支持的,也不知道他们有没有计划推进。。。我把代码简单迁移了一下,开源在链接【3】中,目前(以及可预见的未来)只支持arm64。关于链接【3】,我在本站的帖子【4】中介绍过。我维护的树莓派automagic版内核只能说是just work for hifi,不支持gpu,不支持串口,不支持printk线程安全,当然这些东西网桥也确实用不上,我配置内核时候都关掉了。有编程基础的同学可以尝试一下更完整的,或者其他架构的支持,当然也可以等等上游。目前我在AMD HQPlayer专机和cm4 roon ready上用的automagic preempt,赛扬naa上和rpi4b roon ready上用的full preempt,roon core没用实时内核,用的是一套面向非实时流式数据优化的bmq调度器详见【4】。

【1】https://wiki.linuxfoundation.org/realtime/preempt_rt_versions
【2】https://cdn.kernel.org/pub/linux/kernel/projects/rt/6.6/
【3】https://github.com/zhjie/zhjie_gentoo_repo/tree/master/sys-kernel/raspberrypi-rt-sources
【4】http://erji.net/forum.php?mod=vi ... =2312699&extra=

3.2 BBR patch

Google的BBR patch【5】已经到了第三版,虽然是网络拥堵算法,但对于相对低性能的网桥而言,可以降低CPU负载。Gentoo用户可以直接用我维护的版本【3,4】,debian/ubuntu系用户可以使用【6】,archlinux系用户可以使用【7】,其他用户可参考官方【5】。我所有机器都打了bbr3补丁,不过如果你正用着一代或二代,不需要升级,意思意思得了。

【5】https://github.com/google/bbr/tree/v3
【6】https://xanmod.org/
【7】https://cachyos.org/

3.3 high-hz patch

CPU Timer frequency。古老的服务器或者性能极其低下的soc(再次,例如Beaglebone black)不需要也不能在毫秒这个数量级快速响应用户的请求,采用HZ_100即可;现代网络服务器一般设置为HZ_250;Hqplayer os上使用了所谓低延迟内核,设置为HZ_1000,更适合现代桌面系统和音频处理系统。如果你用的是debian/ubuntu,可以直接搜索lowlatency安装低延迟内核。但如果你有更高的要求,例如付费hifi系统audiolinux上支持HZ_1666,这就需要打些补丁了:Archlinux用户如果在用6.5或更老的内核可使用cachy os维护的内核【6】;如果你用的是6.6内核,目前只能用我维护的版本了,依然在【3,4】可以下载阅读。目前,我的Roon Core设置为HZ_250,HQPlayer和所有常用网桥都设置为HZ2000。其实我还有一套老mbp装Gentoo做roon core,beaglebone black做网桥的破系统寒暑假用,因为没有hq,就给core上的HZ1000,桥太弱上的HZ100。

3.4 kernel compiler patch

让内核编译按CPU支持的指令集优化,而不是路由器固件或通用发行版默认的二十多岁的AMD64/X86_64。其实这补丁早应该进主线内核了,圈内几乎人人都用的,甚至一些发行版把这玩意儿当成收费点了。其实很容易就用上了,有条件必选。

【8】https://github.com/graysky2/kernel_compiler_patch

3.5 cloudflare tcp patch

这是个神奇的patch【9】,能提高数据吞吐量,降低延迟,没仔细看他的代码,考虑到他家做这么大,我是信了的。Xanmod【6】也在维护。当然,一贯的,如果你是Gentoo用户可以直接用我的源【3,4】,都有。

【9】https://blog.cloudflare.com/optimizing-tcp-for-high-throughput-and-low-latency/

回复

使用道具 举报

5
 楼主| 发表于 2023-11-4 01:36 | 只看该作者 来自 荷兰
4. 内核设置

很多优化设置可以在内核中,也可以在系统中,从效果上看两者几乎没有区别。付费系统GentooPlayer把很多优化放在内核,AudioLinux则把几乎所有优化都放在系统。我的方案是尽量放在内核中的,主要因为我一直用的系统是Gentoo(不是GentooPlayer,而是原生的那个),如果你用的系统编译内核不方便,建议按着这几个优化的项目挨个去Google,应该几乎都能找到不用编译内核的解决方案。

4.1 expert users

General setup  --->  Configure standard kernel features (expert users)  --->

先得选上这项,必须选这个才让选rt系统。选了之后点进去顺手删掉Enable PC-Speaker support。就是上古时代的电脑开机时候滴的那声的驱动,做的各种buggy,又没人真用,却人人都有的设备。

4.2 RT

General setup  --->  Preemption Model

需要尽量低延迟,机器性能强又不怕费电的选Fully Preemptible Kernel (Real-Time),差一级的选Automagic preemption mode with runtime tweaking support,或者中庸一些Preemptible Kernel (Low-Latency Desktop)。如果你的机器非常老或者总觉得卡,就选Server,配合后面的HZ_100立竿见影,变成柔和的卡。

4.3 Timers

General setup  --->  Timers subsystem  --->  Timer tick handling

选择Full dynticks system (tickless)。回头我们软件配置的时候要用到,

4.4 RCU

General setup  --->  RCU Subsystem  --->  Make expert-level adjustments to RCU configuration

下面除了force的几条之外挑挑拣拣能选上都选上。也是回头软件配置的时候要用到。

4.5 V3 optimization

Processor type and features  --->  Processor family

如果知道你的cpu,例如AMD Zen 3,就直接选,不知道就选Intel-Native optimizations autodetected by the compiler或者AMD-Native optimizations autodetected by the compiler。当然如果你不知道自己cpu型号但知道自己的cpu支持avx2也可以直接选v3,这适合交叉编译的情况。

4.5 关闭NUMA

Processor type and features  --->  NUMA Memory Allocation and Scheduler Support

关掉,这东西多核才有正提升。

4.6 HZ_2000

Processor type and features  --->  Timer Frequency

冲吧少年。树莓派做网桥是可以支撑HZ_2000的,HZ_1000也可以。Roon Core和NAS之类的机器建议适当降低。但是要知道一件事,更低的延迟总是以性能(吞吐量)降低为代价,如果你设置的太过火,播放的时候会卡到突然停掉,就降低一些。这是因为性能不足够高的情况下,太高的TF值会导致一个CPU时间之内任务都没做完。因此,上古老机器选HZ100吧。

4.7 关闭mitigation

Mitigations for speculative execution vulnerabilities

为了安全可以不关这一项。但最简单的避免出问题的办法是把机器藏起来,关掉或改掉没用的端口,禁用密码登录改用公钥。

4.8 performance governor

Power management and ACPI options  --->  CPU Frequency scaling  --->  Default CPUFreq governor

选择performance。

4.9 网络相关

Networking support  --->  Networking options  --->  TCP: advanced congestion control

选择BBR TCP和Default TCP congestion control (BBR)

Networking support  --->  Networking options  --->  QoS and/or fair queueing

选择Flow Queue Proportional Integral controller Enhanced和Allow override default queue discipline  --->  Default queuing discipline (Flow Queue Proportional Integral controller Enhanced)当然,只要你知道你在选什么,那么一些其他的算法也可以。

回复

使用道具 举报

6
 楼主| 发表于 2023-11-4 01:44 | 只看该作者 来自 荷兰
5. 软件设置

这段是本文重点。关闭超线程,打开或关闭turbo boost,pbo等等设置可以在BIOS里设置,也可以在软件设置,这里就不介绍了。这主要写一些行之有效又很少看到人说的。下面的设置中,假定有四个cpu核心/线程,树莓派啊,j3455到现在的j6412赛扬,各种各样的amd/intel标压cpu之类的烂大街设备都满足。cpu0留给系统使用,cpu1给网卡,cpu2给解码,cpu3给naa或者roon raat。这样的好处,是每次执行一个任务的时候,如果是网卡有关的就直接找cpu1,cpu1也肯定正闲着。如果是解码有关的事都找cpu2,也正闲着。主程序就自己独占了cpu3,也没别人和他抢了(我个人不建议一台机器上同时开着naa和raat,抢DAC时候会print好些日志,强迫症忍不了)。这种原始又粗暴的方法可以有效降低音频应用的延迟。当然,如果你机器发热厉害,或者只有双核,也可以使用下面的方法,把一个核心隔离出来分配给naa/roon。

5.1 rt内核启动参数

确切的说,是在你当前的内核启动参数基础上加上这些东西。有些东西比如threadirqs不加其实也是可以的,写在这里是为了保持逻辑完整。我们的目的,是让系统除了cpu0之外的CPU(也就是cpu1-3)都留着不分配,刚启动时候所有程序都运行在cpu0上。如果你是尊敬的线程撕裂者用户,也可以只保留三个给音频,其他的都分配出去。

如果你用的是grub启动,需要修改/etc/default/grub,在原有GRUB_CMDLINE_LINUX_DEFAULT基础上加上:

  1. GRUB_CMDLINE_LINUX_DEFAULT="threadirqs skew_tick=1 rcu_nocb_poll rcu_nocbs=1-3 nohz=on nohz_full=1-3 kthread_cpus=0 irqaffinity=0 isolcpus=managed_irq,domain,1-3 intel_pstate=disable nosoftlockup tsc=nowatchdog"
复制代码

如果你用的是树莓派,这段东西要写在/boot/cmdline.txt。

5.2 修改音乐播放软件的优先级和程序类型

下面是我在Gentoo openrc网桥上roon ready启动脚本的一部分,意思是让这个程序运行在NICE=-19,RT_PRI=-96,分配给CPU3,也就是最后一个CPU。非Gentoo用户具体修改方法可参考我在本坛的帖子《Roon系统硬核安装笔记》【1】。

【1】http://erji.net/forum.php?mod=vi ... =2253401&extra=

  1. export SSD_NICELEVEL="-19"
  2. user="root:root"
  3. logfile="/tmp/roon.log"
  4. command="taskset"
  5. command_args="
  6.         -c 3 chrt -r 95 /opt/RoonReady/raat_app /etc/raat.conf > $logfile 2>&1
  7. "
复制代码


5.3 修改不同线程的优先级


  1. CHRT_LIST="xhci_hcd ksoftirqd ktimer ahci rtc acpi"

  2. chrt_process() {
  3.     PRI1=89
  4.     for NAME in ${CHRT_LIST}
  5.     do
  6.         PIDS=`ps -eLf | grep "${NAME}" | awk '{print $4}'`
  7.         for PID in ${PIDS}
  8.         do
  9.             if [[ ! -f /proc/${PID}/status ]] || chrt -p -f ${PRI1} ${PID}
  10.             then
  11.                 echo "chrt -p -f pid=${PID} prio=${PRI1}: OK."
  12.             else
  13.                 echo "chrt -p -f pid=${PID} prio=${PRI1}: FAILED."
  14.             fi
  15.         done
  16.         PRI1=$((${PRI1} - 5))
  17.     done
  18. }
  19. chrt_process
复制代码


上面代码中,CHRT_LIST里的字符串来自htop或者ps aux,执行一下这两个命令之一就明白了。其中第一项是你的解码对应的线程,一般系统上都用xhci_hcd(usb3驱动),如果你的主板不支持usb3,或者你不用usb解码/界面,可以不动或者改成你的设备对应的PID。非full preempt系统没有ktimer这条,不过其实不必理会,直接运行这段代码即可,已经考虑了兼容性。


5.4 分配解码和网卡的中断


  1. eth_cpu() {
  2.         NAME="eth"
  3.         echo "eth->cpu"
  4.     IDS=`cat /proc/interrupts | grep "${NAME}" | awk '{print $1}'`
  5.     for ID in ${IDS}
  6.     do
  7.         ID="${ID/:/}"
  8.                 echo ${ID}, 2
  9.         [[ ! -f /proc/irq/${ID}/smp_affinity ]] || echo "2" > /proc/irq/${ID}/smp_affinity
  10.     done
  11. }
  12. eth_cpu
复制代码

  1. usb_cpu() {
  2.     NAME="dwc2_hsotg"
  3.     echo "usb->cpu"
  4.     IDS=`cat /proc/interrupts | grep "${NAME}" | awk '{print $1}'`
  5.     for ID in ${IDS}
  6.     do
  7.         ID="${ID/:/}"
  8.         echo ${ID}, 4
  9.         [[ ! -f /proc/irq/${ID}/smp_affinity ]] || echo "4" > /proc/irq/${ID}/smp_affinity
  10.     done
  11. }
  12. usb_cpu
复制代码


上面NAME里的字符串来自/proc/interrupts,注意如果你用的是光纤网卡,那么eth需要改为对应的字符串;如果你用的不是holo red,那么dwc2_hsotg要改为你的usb驱动xhci_hcd,或者iis卡fe804000之类的。怎么识别出来呢,有个小技巧。如果你还没配置过cmdline.txt启动参数,cat /proc/interrupts的结果应该是如下面网图1这种乱七八糟到处都可能有数字的。



图1,普通系统的中断

如果你按我写的配置了内核,并修改了启动参数,那应该几乎所有行的数字都写在最左边,也就是cpu0下,如下图2所示。这时候你打开roon或者hq放点声音,前面的数字就会增加了。放音乐时候增加的那个就是要修改的网卡,解码器,或者硬盘。如图所示,ahci[0000:00:12.0]这行就是硬盘了,我们回头会做成内存系统,不必理会。eth0这行按名字就知道是网卡了,你在eth_cpu这填eth或者eth0。xhci_hcd有这么多,但可以看到只有 PCI-MSIX-0000:03:00.0 这个设备是激活状态,因为这是我的pcie-usb卡(买的带时钟的国产的就不推荐了),我就可以在NAME这填写。如果你觉得这还有好几个设备也被一起搜进去了,很尴尬啊,那可以把这行改为:


  1.         IDS=`cat /proc/interrupts | grep "${NAME}" | grep "0-edge" | awk '{print $1}'`
复制代码


这就只保留有数据的那个0-edge的通道了。



图2,隔离后刚启动的中断

补充一下,非IO-APIC硬件是不支持动态修改affinity的,这就只能通过内核启动参数限制在cpu0了。

【2】https://cs.uwaterloo.ca/~brecht/servers/apic/SMP-affinity.txt

5.5 PCIE设备的优先级


  1. setpci -v -d *:* latency_timer=b0
  2. export PCI_ID=`lspci|grep TUSB73x0|awk '{print $1}'`
  3. setpci -v -s $PCI_ID latency_timer=ff
复制代码


前面说了我搞了个pcie-usb卡。所有pcie设备都会有个编号,lspci就看到了,还带英文介绍的,我的介绍里这张usb卡是TUSB73x0的,我就把这字符串填写在上面代码里。效果就是,让这张卡的延迟优先级设为ff,高于其他所有卡的b0。如果你有独立网卡或者USB卡,可以写在这。

5.6 内存系统


  1. process_dir() {
  2.     if [ $# == 1 ]; then
  3.         mount none -t tmpfs -o noatime /mnt/.ramdisk/$1
  4.         rsync -a /$1/ /mnt/.ramdisk/$1 --exclude modules --exclude src --exclude cache --exclude db --exclude firmware --exclude portage
  5.         mount -o bind /mnt/.ramdisk/$1/ /$1/
  6.     fi
  7. }

  8. sync && echo 3 > /proc/sys/vm/drop_caches
  9. umount /boot                2>/dev/null
  10. rm -r /mnt/.ramdisk         2>/dev/null

  11. mkdir -p /mnt/.ramdisk/{etc,opt,root,tmp,usr,var}

  12. for dir in etc opt root tmp usr var
  13. do
  14.     echo -e "/$dir ..."
  15.     process_dir $dir
  16. done

  17. sync && echo 3 > /proc/sys/vm/drop_caches
复制代码


之所以这里要折腾一下内存系统,主要是不想再设置ssd的中断了(其实是四个核心用完了...)。上面的脚本很容易看懂并迁移到你的系统上,只需修改mkdir一行和for一行。大约的意思就是,把硬盘根目录上的文件夹,都同步到tmpfs的内存里,之后再把tmpfs的文件夹bind回原来的硬盘文件夹下,这样想要读原文件夹时候就会访问内存而不是硬盘了。

5.7 看看效果吧

经过上面一通折腾,再放会儿音乐,cat /proc/interrupts看看效果,如下图3。



图3,优化后的中断

可以看到不会再增加ahci也就是硬盘的cpu0占用了,说明内存系统果然生效了。看到eth0在cpu0上的数据也不再涨了,从无到有的是cpu1这一列数据,这是因为前面执行了eth_cpu函数把网卡绑定到cpu1了。0-edge xhci_hcd的第一列数据也不变了,cpu2这一列增长了不少。至此我们就把桥的cpu分配好了。至于hq和roon core也可类似优化。



回复

使用道具 举报

7
 楼主| 发表于 2023-11-4 01:44 | 只看该作者 来自 荷兰
6. 小结

本文缘起是看到一位烧友说起xenomai是真正的实时系统,为了避免其他人误会就想写点什么。正好这几天我的Gentoo源因为kernel 6.6发布而大升级,又玩上了最新的augomagic rt内核,就有了本文。其中大部分补丁和代码一些朋友们已经用过很久了,Roon官方论坛也有人使用,会给我提bug,这么多年了可以说是稳定的。也欢迎读者在帖子下留言批评指正。公司个人都可以直接使用我的代码牟利,完全开源免费,也不是gpl3协议,用着有什么问题也可以讨论,但之前有些找我做产品的就算了,不是程序员水平不够。

回复

使用道具 举报

8
 楼主| 发表于 2023-11-4 01:44 | 只看该作者 来自 荷兰
打完收工
回复

使用道具 举报

9
发表于 2023-11-4 02:13 | 只看该作者 来自 四川成都
太专业了点看着头晕,打了这么多字还是支持一下
回复

使用道具 举报

10
发表于 2023-11-4 09:43 | 只看该作者 来自 上海宝山区
本帖最后由 norman_lu 于 2023-11-4 09:50 编辑

我是Holo Red用户,并没有用官方的系统,自己装了gentoo linux,然后用了楼主提供的补丁自己编译了内核,来补充几句。(只适用于树莓派cm4)

  • 可以考虑用clang+ThinLTO来编译内核,甚至可以全局clang+ThinLTO来进一步提升性能

  • 内核配置(在楼主提供的默认配置上做的修改)
  • Timer tick handling (Full dynticks system (tickless)) (我编译的时候默认还是Idle dynticks system (tickless idle))
  • Preemption Model (Automagic preemption mode with runtime tweaking support) (解决了dwc2 usb口用realtime内核会cpu占用异常的问题,表现就是播放音乐时候会有刺耳的滋滋声)
  • Support for init systems, system and service managers (我用的systemd,所以俩都选上)
OpenRC, runit and other script based systems and managers
           
systemd

回复

使用道具 举报

12
 楼主| 发表于 2023-11-4 12:19 来自手机 | 只看该作者 来自 北京
norman_lu 发表于 2023-11-4 09:43
我是Holo Red用户,并没有用官方的系统,自己装了gentoo linux,然后用了楼主提供的补丁自己编译了内核,来 ...

链接里我之前的帖子里讲了如何使用clang lto,这里就没说
回复

使用道具 举报

13
发表于 2023-11-4 15:51 | 只看该作者 来自 浙江杭州
进来膜拜一下,懒+笨的用户比如我还是准备3台X86机器,一台刷daphile,一台刷HQPE OS,一台刷NAA,全部官方镜像最方便了
回复

使用道具 举报

14
 楼主| 发表于 2023-11-4 18:05 来自手机 | 只看该作者 来自 北京
Devastat0r 发表于 2023-11-4 15:51
进来膜拜一下,懒+笨的用户比如我还是准备3台X86机器,一台刷daphile,一台刷HQPE OS,一台刷NAA,全部官方 ...

hq官方镜像确实不错。我用了好久
回复

使用道具 举报

15
发表于 2023-11-4 18:57 来自手机 | 只看该作者 来自 中国
养肥了慢慢看
回复

使用道具 举报

16
发表于 2023-11-4 20:42 | 只看该作者 来自 北京
本帖最后由 lalekuku 于 2023-11-4 22:03 编辑

最喜欢看这种技术贴,太牛了。好在一直跟大佬学习,基本都能看懂,获益匪浅,我自己的rt内核基本就是参照大佬的思路优化的,效果很好,在优化脚本上也加了一些自己的想法。
请教一下,上面的树莓4平均延迟能低到4,属实厉害。这是运行在多高频率下?
我用一块rk3328的板子,性能估计不到树莓4的一半,1G内存,锁定频率在1392Mhz,性能模式,使用HZ_1000,平均延迟能到5或6,是不是也还凑合?
cyclictest  -l 10000 -m -Sp98 -i100 -d0
WARN: stat /dev/cpu_dma_latency failed: No such file or directory
policy: fifo: loadavg: 0.19 0.11 0.09 1/121 1871

T: 0 ( 1870) P:98 I:100 C:  10000 Min:      5 Act:    6 Avg:    5 Max:      31
T: 1 ( 1871) P:98 I:100 C:   9899 Min:      5 Act:    9 Avg:    6 Max:      25

在另一块rk3399板子上延迟如下,2g内存,内核使用HZ_1000,处理器4个小核1.416GHz+2个大核1.8GHz:
cyclictest  -l 10000 -m -Sp98 -i100 -d0
# /dev/cpu_dma_latency set to 0us
policy: fifo: loadavg: 1.65 0.48 0.17 1/191 2147

T: 0 ( 2142) P:98 I:100 C:  10000 Min:      5 Act:    7 Avg:    7 Max:      15
T: 1 ( 2143) P:98 I:100 C:   9958 Min:      5 Act:    6 Avg:    6 Max:      24
T: 2 ( 2144) P:98 I:100 C:   9880 Min:      5 Act:   10 Avg:    7 Max:      13
T: 3 ( 2145) P:98 I:100 C:   9801 Min:      5 Act:    7 Avg:    6 Max:      14
T: 4 ( 2146) P:98 I:100 C:   9717 Min:      3 Act:    3 Avg:    3 Max:      14
T: 5 ( 2147) P:98 I:100 C:   9640 Min:      3 Act:    6 Avg:    3 Max:      12

还有些个人想法借贵贴一起探讨:
1、关于中断,用黑名单可以屏蔽很多无用的设备,进而减少中断,但要小心,别把有用的设备屏蔽掉,否则可能无法启动系统;要想彻底点,还可以精简设备树,禁用无用设备(比如各类显示设备、板载声卡等等);更彻底点,直接在内核编译设置里去掉驱动(编译设置这个不知道我理解的对不对)。
2、HZ_1666用过,但声音在我系统上听起来不是太习惯,似乎有点硬,估计是因系统而异,不知大佬用这个1666有啥不一样的感觉?
3、bbr3在xanmod里似乎是直接替换了v2和v1,编译设置时没有v1和v2的选项,只有一个bbr,不知是不是这样?
4、给板子插了usb网卡,以扩充网口,用ip a命令查看网卡信息如下:
自带网卡:eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq master br0 state DOWN group default qlen 1000
USB网卡:eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_pie master br0 state UP group default qlen 1000

可以看到自带网卡没有打开fq_pie ,而usb网卡却打卡了fq_pie,这是怎么回事?我在sysctl.conf里是设置了fq_pie参数的,为什么只有usb网卡生效?(请忽略里面的state DOWN,在UP时也是一样的信息
5、大佬能不能抽空讲一讲怎么精简系统?现在用的dietpi其实已经比较精简了,但感觉还是有冗余,后台服务有些也不敢随便动。

6、xanmod啥时候能把rt内核更新到6.5以上啊?

回复

使用道具 举报

17
发表于 2023-11-4 20:48 来自手机 | 只看该作者 来自 上海
太专业了
回复

使用道具 举报

18
发表于 2023-11-4 22:21 | 只看该作者 来自 云南昆明
先收藏了,
回复

使用道具 举报

19
 楼主| 发表于 2023-11-4 23:25 | 只看该作者 来自 北京

看吧,我一般不撘楼,再有新东西会发新帖
回复

使用道具 举报

20
 楼主| 发表于 2023-11-4 23:51 | 只看该作者 来自 荷兰
lalekuku 发表于 2023-11-4 20:42
最喜欢看这种技术贴,太牛了。好在一直跟大佬学习,基本都能看懂,获益匪浅,我自己的rt内核基本就是参照大 ...

挺多的,简单回答下吧


1. 3328跑分其实挺强的,和树莓派比单核大约是1 : 1.5吧。3399单核多核跑分都比树莓派超频后更强一些。但是延迟和性能并不是完全正比的,和架构有关,像arm就明显不如x86,在相同cpu性能的情况下。不过话说回来,延迟到底有什么用,这玩意儿没法说的。手里有多少设备,挨个试试哪个听着好听就行。听不出来的话,要么哪个方便哪个来,要么哪个技术先进选哪个都行。。。

2. 设备树和驱动程序的关系这个,每种设备都是不一样的。比如x86系统一般不用设备树维护,而用udev的多,树莓派我也用的udev维护。我估计前面Norman的Gentoo也是用udev的。


3. 精简系统其实并没什么实际意义,更多的是强迫症行为。因为多数文件启动之后也就不再读了,实在不行都放内存里了速度也够了,事实上我这测试了内存缓存+nvme甚至都不一定干的过nvme ext4文件系统直接读,如果nvme硬盘性能足够强,就完全没精简的必要了。

4. xanmod是补丁集合,技术实力有限,而且求稳的,高版本rt可能要很久了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | -注册-

本版积分规则

Archiver|手机版|粤icp备09046054号|耳机网-耳机大家坛

粤公网安备 44030602000598号 耳机大家坛、www.erji.net、网站LOGO图形均为注册商标

GMT+8, 2024-11-27 08:45

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表