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

你的HQPlayer naa用了RT内核吗?naa的优先级机制笔记

[复制链接]
跳转到指定楼层
1
发表于 2023-12-1 16:57 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式 来自 北京
本帖讨论两个问题,HQPlayer naa的优先级机制,以及官方提供的隐藏脚本接口。

1. 引言,来自Miska的建议

起因是群友发来的下面这张图。简单的说HQ作者Miska说了两个事:一是要full tickless,这个争议不大;二是不要把naa设成fifo(也就是rt进程),不要做cpu隔离。


图1. HQPlayer作者Miska在Audiophile论坛的发言

我并不打算谈什么方案声音好,甚至不评论什么方案性能好,只是展开说一下Miska为什么会这么说,如果不实时、不隔离对naa适用,那对roon ready是否也适用呢?延伸至此我想介绍一下naa的优先级机制是怎样的。一贯的,还有我的解决方案和代码,但和往常一样,这是一个草稿仅供参考,我不是程序员实现的很糙,你可以按自己的偏好调整,就好像使用我维护的内核包【1】你可以自由选择PREEMPT_RT/automagic/BMQ,也可以选择HZ_2000(gentooplayer/autolinux),HZ_1000(hqplayer os),或者HZ_250(ubuntu)。本帖类似之前我对Roon的介绍【2】,侧重各个线程的作用,以及如何利用官方有意无意提供的接口深度修改。如果你是普通HQ用户可能会觉得无聊,更侧重于面向强迫症烧友、技术控和公司读者。

对实时内核及其用处还不了解的同学可参考我之前在绿檀帖子【1】的简介部分,关于两种通用的PREEMPT_RT内核也就是通常所说的实时内核、同团队最新推出的automagic实时内核,以及xenomai内核、pru等定制工业实现。前两种内核补丁结合naa DSD1024补丁的x86和树莓派内核的Gentoo Linux包都是我在维护【3】,目前是6.6.3,其中automagic的树莓派版官方还没推出,暂时用的是我迁移的版本请谨慎使用。

【1】http://erji.net/forum.php?mod=viewthread&tid=2317889
【2】http://erji.net/forum.php?mod=viewthread&tid=2253401
【3】http://erji.net/forum.php?mod=viewthread&tid=2312699


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

2. naa的优先级机制

2.1 naa的优先级机制和Miska的方案
和Roon相对比较清晰的区分线程不同,hqplayer naa所有功能都在同一个进程之内使用相同的线程名无法简单区分。在默认配置下播放的时候,如下图2所示。可以看到,naa实现的可是比roon干净多了,一共只有三个线程,NI都是10,说明所有线程的NICE都是10,考虑到最高优先级是20,这是一个比较稳妥合理的数字。NI,或者说nice值是对非实时调度才生效的,前面那个PRI是对实时线程生效的,RT最高,-99其次,图中的三个分别是10, -3, -4,低于大多数内核态进程了,但高于用户态进程,这是一个保守的数字。这三个线程中,NI=10的是启动程序用的。打开大约一两秒钟会启动NI=-3的线程,用于和HQPlayer通讯。等到开始播放音乐了,就会启动那个NI=-4的线程,专门播放。


图2. 默认配置下HQPlayer naa在Linux下的线程优先级

说到这,读者应该能想清楚引言中HQ作者Miska的意思了吧。他说naa不要设置成naa为rt进程,是因为播放和通讯用的两个线程已经在程序中被强行定义为-3和-4的实时线程了,他并不是告诉读者实时线程没用,而是说你用chrt命令以实时进程启动naa是没用的,感兴趣的读者可以试试,执行chrt -r 96 networkaudiod之后,会启动一个主线程为-97,播放和通讯的两个线程的优先级依然是-4和-3。这样做,和Miska默认实现相比反而有副作用,用于和HQPlayer心跳的NI=10的线程优先级特别高,高于播放和通讯的线程了,好嘛。不过读者千万不要正好看到这关掉网页,马上反转。

2.2 另外一个naa优先级方案

我没用HQ提供的naa img,是自行定制的所以上面的截图很干净除了用于截图的htop over ssh没别的东西。如果你登录自己的naa,一般来说会发现比我的截图多好多进程,都是用户态的,一般来说优先级都是低于naa设置的NI=10的。这么看来Miska的方案思路清晰,很不错。但其实系统上还会有几十上百个内核态进程,这时候-3和-4的通讯、播放模块就弱的很了。我目前使用的方案,10, -3, -4分别被修改为-1, -96, -97。和主机心跳的线程略微提升,通讯和播放的优先级高于大多数内核态进程。当然,也可以选择略微稳妥的10, -96, -97。让心跳的优先级低一些,确实没什么大用。具体的实现代码详见第三大节。

2.3 关于cpu隔离

Miska对于cpu隔离的看法是一贯如此的。他做的HQPlayer OS上使用了irqbalance,而没做隔离——对此我是完全赞成的,我的HQPlayerd也是如此。和计算密集型的HQPlayerd不同,naa的cpu占用率其实是非常低的,即便在门总大力推广的Beaglebone开发板上也只有60%多。我用的传家宝j3455性能要好一些,在10%左右(DSD1024)。

然而给naa做cpu隔离目的并不是保护naa,反而是保护naa不要侵占其他进程的资源,尤其是中断资源,那就是网卡和usb。我不太严谨的边听音乐边随便看了一下naa的占用就不截图了,naa占6%,usb占5%,网卡占8%。如果换成树莓派cm4,usb甚至会达到10%多。因此我的方案是,分配cpu3给naa,cpu2给usb,cpu1给网卡,其他进程都给cpu0,省得naa去欺负网卡和usb。如果你的网桥有更多cpu内核,例如6个,建议把其中的三个都分给naa,甚至可以尝试上irqbalance辅助,让心跳、通讯、播放更均衡。


回复

使用道具 举报

3
 楼主| 发表于 2023-12-1 16:59 | 只看该作者 来自 北京
本帖最后由 中关村东路 于 2023-12-1 17:16 编辑

3. naa提供的隐藏脚本接口,以及接口使用实例

这是个有意思的功能,很隐蔽,官方也没文档描述。登录naa,看看配置文件夹 /etc/networkaudiod/,可能会有一个networkaudiod.xml文件,一般是用来配置录音声卡的,不用管他。现在你可以编辑一个文件,执行:

  1. echo "echo echo > /tmp/omg" > /etc/networkaudiod/onconnected
  2. chmod +x /etc/networkaudiod/onconnected
复制代码


之后用你的方式重启naa服务,或者naa机器。连上HQPlayerd之后,你会发现/tmp/文件夹下出现了一个文件omg,里边写着echo。这就是我要介绍的naa偷偷提供的功能。目前我知道的共有四种trigger:onconnected、ondisconnected、onstart、onstop。接下来我会以onstart为例,介绍如何实现我在上一节提到的naa优先级方案。


  1. echo "nohup sh /root/rt.sh >/dev/null 2>&1 &" > /etc/networkaudiod/onstart
  2. chmod +x /etc/networkaudiod/onstart
复制代码


之后我们编辑具体的实现rt.sh

  1. sleep 1.5

  2. PRI0=10
  3. PRI1=-3
  4. PRI2=-4

  5. TAR2=95
  6. TAR3=96

  7. NAME="networkaudiod"

  8. PIDS=`ps -eLF | grep "${NAME}" | awk '{print $4}'`
  9. for PID in ${PIDS}
  10. do
  11.     STAT=-1
  12.     [[ ! -f /proc/${PID}/status ]] || STAT=`cat /proc/${PID}/stat | awk '{print $18}'`
  13.     if [ "${STAT}" == -1 ]; then
  14.         continue
  15.     fi

  16.     if [[ "${STAT}" == "${PRI0}" ]]; then
  17.         echo $PRI0
  18.         continue
  19.     fi

  20.     if [[ "${STAT}" == "${PRI1}" ]]; then
  21.         echo $PRI1
  22.         if [[ ! -f /proc/${PID}/status ]] || chrt -p -f ${TAR2} ${PID}
  23.         then
  24.             echo "chrt -p -f pid=${PID} prio=${PRI1}: OK."
  25.         else
  26.             echo "chrt -p -f pid=${PID} prio=${PRI1}: FAILED."
  27.         fi
  28.         continue
  29.     fi

  30.     if [[ "${STAT}" == "${PRI2}" ]]; then
  31.         echo $PRI2
  32.         if [[ ! -f /proc/${PID}/status ]] || chrt -p -f ${TAR3} ${PID}
  33.         then
  34.             echo "chrt -p -f pid=${PID} prio=${PRI1}: OK."
  35.         else
  36.             echo "chrt -p -f pid=${PID} prio=${PRI1}: FAILED."
  37.         fi
  38.         continue
  39.     fi
  40. done
复制代码


在上面的两个文件中,我们在音乐播放onstart时立即触发执行rt.sh这个脚本。脚本一开始先暂停1.5秒,等等我的老爷机启动naa播放线程,你的机器好可改成1。这时候,系统中应该出现了三个networkaudiod线程了,优先级分别为10, -3, -4。我要做的就是先搜出所有名为networkaudiod的线程id,解析出来放在STAT里。如果等于10,就不理他,如果等于-3就改成-96,如果等于-4就改成-97。好了,大功告成。




回复

使用道具 举报

4
 楼主| 发表于 2023-12-1 17:00 | 只看该作者 来自 北京
小结。

本帖通过介绍HQPlayer naa的优先级机制及其隐藏功能,讨论了Miska对实时进程、cpu隔离的观点,并附上实现例程。欢迎感兴趣的网友留言。


回复

使用道具 举报

5
 楼主| 发表于 2023-12-1 17:00 | 只看该作者 来自 北京
打完收工
回复

使用道具 举报

6
发表于 2023-12-1 21:21 | 只看该作者 来自 日本
先不讨论DAC之后的模拟信号,有没有办法量化这些修改对信号的影响,这样比较容易客观比较。
回复

使用道具 举报

7
 楼主| 发表于 2023-12-1 21:41 | 只看该作者 来自 北京
shine_bnu 发表于 2023-12-1 21:21
先不讨论DAC之后的模拟信号,有没有办法量化这些修改对信号的影响,这样比较容易客观比较。

有质疑的精神很好,但你提这问题说明你不但完全不了解实时内核,也没看我推荐的链接。打开之后主贴是介绍,置顶的回帖就是第三方数据。

简单的说,naa正在播放音乐呢,这时候硬盘读写需要响应,HQ主机的数据需要传输,心跳信号需要处理,几十上百个内核线程需要调度,都需要CPU去响应。如果用的不是近年来的x86 cpu,延迟甚至会达到ms量级,别说能不能量化了,录音师都能听出区别。
回复

使用道具 举报

8
发表于 2023-12-2 08:34 | 只看该作者 来自 日本
中关村东路 发表于 2023-12-1 21:41
有质疑的精神很好,但你提这问题说明你不但完全不了解实时内核,也没看我推荐的链接。打开之后主贴是介绍 ...

完全没有质疑的意思,我原意只是字面意思。看了楼主推荐的第一个链接,发现cyclictest就是我想要的,谢了。

回复

使用道具 举报

9
发表于 2023-12-2 11:53 来自手机 | 只看该作者 来自 中国
强贴留名
回复

使用道具 举报

10
发表于 2023-12-2 11:55 | 只看该作者 来自 中国
实时的确更清晰,解析力更高--佩服大佬的技术!
回复

使用道具 举报

11
 楼主| 发表于 2023-12-2 13:43 | 只看该作者 来自 北京
本帖最后由 中关村东路 于 2023-12-2 14:02 编辑
shine_bnu 发表于 2023-12-2 08:34
完全没有质疑的意思,我原意只是字面意思。看了楼主推荐的第一个链接,发现cyclictest就是我想要的,谢了 ...

其实我是并不建议测速的,一些优化能听出区别就用,听不出来就算了。而且测速跑分什么的经常需要在内核中埋点,我机器上都是去掉的。我在绿檀上介绍的都是非常基础的技术,没钱买高端服务器时候我自己跑计算的机器上用的,没有伪科学,也没有纯忽悠小白的指标。只不过之前我的优化目标是吞吐量,总计算时间少,现在希望非并发、高负载、流式数据处理的CPU延迟低,别卡。


过度理性玩儿Hifi没意义也没意思
回复

使用道具 举报

12
发表于 2023-12-2 17:09 | 只看该作者 来自 江苏
中关村东路 发表于 2023-12-2 13:43
其实我是并不建议测速的,一些优化能听出区别就用,听不出来就算了。而且测速跑分什么的经常需要在内核中 ...

大神,ROCK64作NAA,能用RT内核吗?
回复

使用道具 举报

13
 楼主| 发表于 2023-12-2 18:32 | 只看该作者 来自 荷兰
handsdady 发表于 2023-12-2 17:09
大神,ROCK64作NAA,能用RT内核吗?

我没用过,不过这是老板子了肯定能
回复

使用道具 举报

14
发表于 2023-12-2 19:34 来自手机 | 只看该作者 来自 中国
中关村东路 发表于 2023-12-2 18:32
我没用过,不过这是老板子了肯定能

是不是arm需要自己编译内核?没法直接x86那样容易更换?
回复

使用道具 举报

15
 楼主| 发表于 2023-12-2 19:35 | 只看该作者 来自 荷兰
handsdady 发表于 2023-12-2 19:34
是不是arm需要自己编译内核?没法直接x86那样容易更换?

这个我倒是没去了解过,我一直用的Gentoo Linux,不但内核整个系统都得自己编译..
回复

使用道具 举报

16
 楼主| 发表于 2023-12-2 19:47 | 只看该作者 来自 荷兰
handsdady 发表于 2023-12-2 19:34
是不是arm需要自己编译内核?没法直接x86那样容易更换?

https://packages.debian.org/bookworm/linux-image-rt-armmp

供参考
回复

使用道具 举报

17
发表于 2023-12-7 17:21 | 只看该作者 来自 北京丰台
本帖最后由 lalekuku 于 2023-12-7 17:44 编辑

又见技术贴,感谢分享。
好好拜读,深入学习一下。我的hq和naa都用了rt内核,都做了cpu隔离和优先级设置,中断也做了隔离和优先级设置,其中naa设置的更细致一些,效果还是明显的。
大佬有arm64可用的优化过的gentoo系统镜像吗?看你的gentoo那么干净,太诱人了,也想试试

如果大佬允许的话,我想尝试往我的板子上移植一下,不知可否?
回复

使用道具 举报

18
发表于 2023-12-7 17:38 | 只看该作者 来自 北京丰台
handsdady 发表于 2023-12-2 17:09
大神,ROCK64作NAA,能用RT内核吗?

必须能用,但要自己编译和优化。我的主力板子就是rk3328处理器
回复

使用道具 举报

19
 楼主| 发表于 2023-12-7 19:38 | 只看该作者 来自 北京
lalekuku 发表于 2023-12-7 17:21
又见技术贴,感谢分享。
好好拜读,深入学习一下。我的hq和naa都用了rt内核,都做了cpu隔离和优先级设置, ...

Gentoo官方有,下面链接供参考。【1】是目录,【2】是3288,你的设备应该是类似。

【1】https://wiki.gentoo.org/wiki/Embedded_Handbook
【2】https://wiki.gentoo.org/wiki/Libre_Computer_Renegade
回复

使用道具 举报

20
发表于 2023-12-7 20:37 | 只看该作者 来自 北京
中关村东路 发表于 2023-12-7 19:38
Gentoo官方有,下面链接供参考。【1】是目录,【2】是3288,你的设备应该是类似。

【1】https://wiki. ...

好的,我去看看
回复

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-12-2 02:03

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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