耳机网-耳机大家坛

标题: 你的HQPlayer naa用了RT内核吗?naa的优先级机制笔记 [打印本页]

作者: 中关村东路    时间: 2023-12-1 16:57
标题: 你的HQPlayer naa用了RT内核吗?naa的优先级机制笔记
本帖讨论两个问题,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



作者: 中关村东路    时间: 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辅助,让心跳、通讯、播放更均衡。



作者: 中关村东路    时间: 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。好了,大功告成。





作者: 中关村东路    时间: 2023-12-1 17:00
小结。

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



作者: 中关村东路    时间: 2023-12-1 17:00
打完收工
作者: shine_bnu    时间: 2023-12-1 21:21
先不讨论DAC之后的模拟信号,有没有办法量化这些修改对信号的影响,这样比较容易客观比较。
作者: 中关村东路    时间: 2023-12-1 21:41
shine_bnu 发表于 2023-12-1 21:21
先不讨论DAC之后的模拟信号,有没有办法量化这些修改对信号的影响,这样比较容易客观比较。

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

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

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

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


作者: sszj2010    时间: 2023-12-2 11:53
强贴留名
作者: 万远    时间: 2023-12-2 11:55
实时的确更清晰,解析力更高--佩服大佬的技术!
作者: 中关村东路    时间: 2023-12-2 13:43
本帖最后由 中关村东路 于 2023-12-2 14:02 编辑
shine_bnu 发表于 2023-12-2 08:34
完全没有质疑的意思,我原意只是字面意思。看了楼主推荐的第一个链接,发现cyclictest就是我想要的,谢了 ...

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


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

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

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

作者: 中关村东路    时间: 2023-12-2 18:32
handsdady 发表于 2023-12-2 17:09
大神,ROCK64作NAA,能用RT内核吗?

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

作者: handsdady    时间: 2023-12-2 19:34
中关村东路 发表于 2023-12-2 18:32
我没用过,不过这是老板子了肯定能

是不是arm需要自己编译内核?没法直接x86那样容易更换?
作者: 中关村东路    时间: 2023-12-2 19:35
handsdady 发表于 2023-12-2 19:34
是不是arm需要自己编译内核?没法直接x86那样容易更换?

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

作者: 中关村东路    时间: 2023-12-2 19:47
handsdady 发表于 2023-12-2 19:34
是不是arm需要自己编译内核?没法直接x86那样容易更换?

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

供参考

作者: lalekuku    时间: 2023-12-7 17:21
本帖最后由 lalekuku 于 2023-12-7 17:44 编辑

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

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

作者: lalekuku    时间: 2023-12-7 17:38
handsdady 发表于 2023-12-2 17:09
大神,ROCK64作NAA,能用RT内核吗?

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

作者: 中关村东路    时间: 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

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

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

好的,我去看看

作者: lalekuku    时间: 2023-12-8 20:30
方法确实好使
但为啥我的naa只有2个线程?一个主线程,一个默认rt优先级-4的线程,没有-3的线程。奇怪了
作者: Jackyng    时间: 2024-1-8 12:36
你好楼主,你说的东西很专业,我也看不太懂。我是用mac os玩hqplayer的,应该如何正确选择NAA网桥? 咸鱼淘宝杂七杂八,不知道怎么弄
作者: 中关村东路    时间: 2024-1-8 15:47
Jackyng 发表于 2024-1-8 12:36
你好楼主,你说的东西很专业,我也看不太懂。我是用mac os玩hqplayer的,应该如何正确选择NAA网桥? 咸鱼淘 ...

这我就不懂了,贵的好?kidding...


如果不想折腾的话,要么买大厂成品,要么看看hqplayer的推荐列表直接刷官方给的rom。在下面页面搜索"Recommended hardware"和"Devices with built-in NAA"


https://www.signalyst.com/consumer.html

作者: Jackyng    时间: 2024-1-10 23:09
中关村东路 发表于 2024-1-8 15:47
这我就不懂了,贵的好?kidding...

可否举个例子呀?关于网桥这一块我真不了解,有哪些大厂或者成品名字吗?
我现在都不知道应该搜什么

作者: lalekuku    时间: 2024-6-8 21:20
本帖最后由 lalekuku 于 2024-6-8 21:31 编辑

大佬,请教一个问题。
我正在用你的精简版gentoo系统,声音非常不错。
我想着把squeezelite也加进去,用起来方便一些。用拷贝的方式真弄成了(这版gentoo我不会安装软件,只能简单粗暴的拷贝),squeezelite的声音也很好。
但发现一个问题,squeezelite只能输出48khz,所有其他采样率的音频文件都转换成了48khz输出,而且不能播放dsd。
想让它以音频文件的原始采样率输出,不做重采样,该怎么做才好?

BTW:用类似的方法把album player也装进去了,使用它的upnp功能可以正常输出各种采样率的文件,并没有转换成48khz。不知道为啥squeezelite就不行,很奇怪。




作者: 中关村东路    时间: 2024-6-9 15:22
lalekuku 发表于 2024-6-8 21:20
大佬,请教一个问题。
我正在用你的精简版gentoo系统,声音非常不错。
我想着把squeezelite也加进去,用 ...

不懂啊。。没用过这两个

作者: lalekuku    时间: 2024-6-9 16:42
中关村东路 发表于 2024-6-9 15:22
不懂啊。。没用过这两个

我再研究研究

作者: andrea74    时间: 2024-6-9 18:34
lalekuku 发表于 2024-6-8 21:20
大佬,请教一个问题。
我正在用你的精简版gentoo系统,声音非常不错。
我想着把squeezelite也加进去,用 ...

拷贝的时候有没有把squeezelite的conf也拷贝过来,应该是设置的问题
作者: lalekuku    时间: 2024-6-9 21:03
andrea74 发表于 2024-6-9 18:34
拷贝的时候有没有把squeezelite的conf也拷贝过来,应该是设置的问题

squeezelite的conf是指squeezelite的启动参数配置文件?都设过。印象中几个月前是正常的,这两天突然发现强制重采样48k了,什么都没动过

作者: lalekuku    时间: 2024-8-18 15:25
请教一下,hqos里的naa,运行时无法触发onstart脚本,怎么设都不行 ,可能是什么原因呢?
在其他系统里单独安装的naa没这个问题。

作者: 中关村东路    时间: 2024-8-19 21:43
lalekuku 发表于 2024-8-18 15:25
请教一下,hqos里的naa,运行时无法触发onstart脚本,怎么设都不行 ,可能是什么原因呢?
在其他系统里单 ...

这就不知道了..要不用别的系统?

作者: lalekuku    时间: 2024-8-19 22:00
中关村东路 发表于 2024-8-19 21:43
这就不知道了..要不用别的系统?

看来只能如此了,

作者: tsilon    时间: 2024-11-11 15:36
结合"Roon和HQPlayer Embedded双机同步实现hqplayerd实时线程",把ssh root@192.168.1.11 '/root/rt.sh'放上面naa的 /root/rt.sh也起作用了




欢迎光临 耳机网-耳机大家坛 (http://erji.net/) Powered by Discuz! X3.2