本帖最后由 中关村东路 于 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辅助,让心跳、通讯、播放更均衡。
|