Monibuca v5 实现零拷贝 BufReader
背景
在开发高 IO 的程序都会面临一个问题,就是如何提供从网络层读取数据的性能。
直接读取
直接读取类似下面这种情况
复制代码
优点是简单,而且延迟较低,可以立即获取到想要长度的数据。缺点也很明显,需要频繁 make,更关键的是需要频繁调用 syscall,造成 CPU 损耗。
使用 bufio.Reader
这个是标准库提供的,带缓冲的读取方式
复制代码
原理是一次读入 4096(默认)的数据到缓存中,减少多次 syscall 。然后再从缓存中读取需要的数据,不够再从网络测读取。
但是:
没有解决需要 make 导致的 gc 问题
增加了内存复制操作
基于 v5 内存分配器实现的零拷贝 BufReader
v5 的内存分配器看这篇:《Monibuca v5 中实现优雅内存分配器_Go_不卡科技_InfoQ写作社区》
基本原理:
从分配器里面获取一块内存作为缓存
一次读入一大块数据到缓存中
缓存中再读取需要的数据,并且可以手动控制回收部分内存
当音视频数据在 ringbuffer 中将要被覆盖的时候,就把对应的内存回收。其他临时的数据(比如长度、时间戳等),都可以在使用完后立即回收。
橘色的内存块是黄色的切片,因此不需要拷贝就能直接使用,在音视频数据的缓存过程中也保持碎片形式,不进行合并操作,在发送的时候使用 writev 批量发送就避免了内存复制。后续可以再结合更底层的网络 IO 库进行进一步的优化底层传输效率。
下面是和 bufio 的 Reader 作一个性能测试对比:
版权声明: 本文为 InfoQ 作者【不卡科技】的原创文章。
原文链接:【http://xie.infoq.cn/article/44e6bab234f9795dc9d5c1bb5】。文章转载请联系作者。
评论