NJU-ProjectN / am-kernels

AbstractMachine kernels
Other
61 stars 45 forks source link

PA2 声卡加锁 ( #5 continue) #7

Closed rijuyuezhu closed 1 year ago

rijuyuezhu commented 1 year ago

5 中提到了 PA2 中 nemu 实现声卡的问题。固然进程间加锁超出了 ICS 课程的范围,但是作为封装良好的开源库,SDL 在手册中给定了使用规范和约束:

SDL_OpenAudio

Description

desired->callback

... This function usually runs in a separate thread, and so you should protect data structures that it accesses by calling SDL_LockAudio and SDL_UnlockAudio in your code. ...

是故学生不需要理解其原理,造成噪声等问题的原因是未按照手册要求使用 API。学生不需要使用朴素的进程锁,只需要严格按照要求调用 SDL 的 API LockAudioUnlockAudio 即可。

这是一次很好的训练,告知学生使用库函数时不可凭空猜测其用法,而是应当仔细阅读文档。经过测试,在没有进行同步时,遇到噪音的可能性是不小的,学生大概率会遇到这个问题。可以在讲义中添加仔细阅读 SDL 文档的提示。任何认真阅读了 SDL_OpenAudio 文档的学生尽管可能不能理解问题的本质,但是应该有能力正确实现 API。如此一来,也不需要对框架代码进行修改(虽然似乎 am_native 也没有正确实现)。

添加的提示可以是:

!!! 在播放音乐的时候出现不明噪声

    原因可能是没有严格遵守 SDL 的 API 规范。在 [SDL 库的文档](https://wiki.libsdl.org/SDL2/CategoryAPI)中提及了 SDL 库的 API 的使用规范和约束。使用库函数时,**任何未满足规范和约束的使用的结果是未知的**。请确保仔细阅读文档并严格满足 API 规范和约束。
rijuyuezhu commented 1 year ago

另外,这个issue可能放在nemu下比较合适。

sashimi-yzh commented 1 year ago

经过测试,在没有进行同步时,遇到噪音的可能性是不小的

你可以提供一些你那边测试情况的数据吗? 我这边跑超级玛丽和仙剑, 都没有明显感觉到噪声的存在, 所以在我看来, 这个问题并没有致命到不解决不行的地步.

另外我在考虑换成SDL_QueueAudio(), 它的编程模型更简单.

rijuyuezhu commented 1 year ago

经过测试,在没有进行同步时,遇到噪音的可能性是不小的

你可以提供一些你那边测试情况的数据吗? 我这边跑超级玛丽和仙剑, 都没有明显感觉到噪声的存在, 所以在我看来, 这个问题并没有致命到不解决不行的地步.

另外我在考虑换成SDL_QueueAudio(), 它的编程模型更简单.

按照我的实现,若不进行进程间同步,在 AM 到 NEMU 通信中,若使用单个字节的拷贝(较为低效),则小星星有约 1/2 的概率会出现噪音(每个音符变为沉闷的声音)与杂音的现象;一首 5:00 左右的歌曲则会导致底乐嘈杂、人声时常伴随噪音等现象,复现概率极大,基本每次都有。但若在 AM 和 NEMU 通信中进行优化,每次拷贝四个字节,则噪音大部分消失,偶尔仍会发生。

上述测试主要通过是通过 am-test 中的 audio 进行的,超级玛丽和仙剑本身在 NEMU 上运行得就很卡,我想是不是噪音都影响不大,主要听个响(笑

另外,猜测复现概率和运行性能有关。从 AM 到 NEMU 通信的频率越高(即 AM 代码效率越高/NEMU运行越快/AM到NEMU通信越低效),则发生进程间冲突的概率会更高。我的测试中关闭了所有 TRACE、DIFFTEST、DEBUG FLAG 等,在 i5-1340P *16 上的 Ubuntu 22.04.3 LTS 进行测试。测试结果确实有可能有主观性。但是周围写得比较快的同学似乎都有发现这个问题,而且普遍调了不少时间未果。

sashimi-yzh commented 1 year ago

我移植了一段《Bad Apple!!》的PV, 确实复现出上述问题.

我在讲义中添加了杂音相关的提示, 感谢你对这个问题的分析和建议!