|
本帖最后由 zasflower 于 2023-4-17 19:46 编辑
软件的缓存问题实际上远比你想象的要复杂。
首先,软件内部不会频繁的去移动内存。平移内存是很费时的,而是用内存的指针地址代替。
而且软件为了不引起数据混乱,一般设计成单线程不会设计成多线程以免引起死锁和数据混乱因为频繁的在读写操作内存。DSP代码会频繁的访问和写入内存,大约每秒500万次的数据操作量。每个数据占用64bit,双精度。
首先,缓存代码创建一个96kb的内存空间。
和操作系统请求某flac文件的16kb磁盘内容。分开请求6次以免引起系统io阻塞。
这个内容是2进制对齐的。
96kb读取完毕后交给flac解码器,指示flac解码器从96kb的0开始处指针读取96kb内存,flac解码大约一秒的数据放到数据输出缓存。交给DSP程序代码。
DSP程序代码处理这1秒的音频解码后的数据。交给声卡。
现在数据扔给声卡了。96kb不一定flac解码器是刚好就是用96kb。因为虽然磁盘读取是16kb 16kb对齐的。解码器不一定。
flac解码器现在标记96kb哪一部分是脏数据(已经用完的)
在flac解码器和DSP处理程序处理数据的时候程序都不会从磁盘读取文件。以免被操作系统挂起引起声音卡顿。
现在flac解码器和DSP音效处理程序都已经处理完数据。1秒的缓冲区数据已经接近用完。
重新开始和操作系统请求磁盘数据。
假设现在延迟正常,稳定,这一切都没有问题。所以我说机械也并不是没有延迟,只是延迟稳定而已。
现在假设延迟异常。缓存代码和操作系统请求16kb新数据。
现在延迟异常,磁盘IO卡住。操作系统挂起程序,不再给程序分配CPU。
整个程序卡死。
然后声卡1秒的DSP输出声音数据播放完了。
程序仍然还被操作系统因为磁盘IO挂起卡住。声音卡住。操作系统要因为磁盘IO阻塞挂起程序,程序是没有什么办法的。
延迟正常的情况下这一切都没什么问题,延迟波动过大延迟异常的情况下操作系统将因为磁盘IO阻塞直接挂起程序。不再让程序执行CPU代码直到磁盘可以访问数据磁盘IO正常。
这就是为什么会有把磁盘文件全部缓存到内存再进行播放的操作。整个播放过程完全不和磁盘IO请求数据。程序也就不会被操作系统因为磁盘IO问题挂起导致无法在CPU执行代码整个程序完全被冻结。磁盘IO延迟异常卡住,程序就会被操作系统挂起冻结。此时整个程序无论界面,代码全部被冻结直到磁盘IO正常。
还说播放过程中请求32MB的缓存,这不扯淡么,在操作系统这32MB完全准备好和磁盘IO可用前,整个程序都被冻结。代码不执行,CPU转交给别的没有磁盘io卡住的程序使用。所以现在请求文件都是请求一小段,更新一下界面,再请求一小段。这样程序界面和代码执行才不会被系统冻结(或者被短暂冻结,比如0.02秒 0.01秒 20毫秒 10毫秒,对用户几乎不影响)。
这就是为什么磁盘永远都会有延迟。但是延迟稳定不会过大波动很重要。
和打游戏一样,服务器永远都会有延迟。程序也会设计延迟机制。但是延迟不会波动过大很重要。
你网络如果不稳定,啥视频播放器都白搭。和看直播一样,你网络不稳定画面卡顿怪视频播放器?视频播放器没缓冲区么?你自己网络的波动过大不稳定的问题而已。自己网络问题不要怪缓冲区,别人就没延迟么?但是人家延迟稳定啊,别人网络稳定的视频都不卡。
还说我拿游戏服务器举例不对。两个网络连接服务器,都有延迟。一个延迟90 100 100,有延迟,波动小,最小90,最高110。一个延迟一会20 一会500 一会1000,最小20,最大1000。是头猪都知道应该选100延迟那个服务器。
|
|