写点什么

Monibuca v5 实现零拷贝 BufReader

作者:不卡科技
  • 2024-04-22
    广东
  • 本文字数:602 字

    阅读完需:约 2 分钟

背景

在开发高 IO 的程序都会面临一个问题,就是如何提供从网络层读取数据的性能。

直接读取

直接读取类似下面这种情况


b:= make(100)io.ReadFull(conn,b)
复制代码


优点是简单,而且延迟较低,可以立即获取到想要长度的数据。缺点也很明显,需要频繁 make,更关键的是需要频繁调用 syscall,造成 CPU 损耗。


使用 bufio.Reader

这个是标准库提供的,带缓冲的读取方式


reader:=bufio.NewReader(conn)b:= make(100)io.ReadFull(reader,b)
复制代码


原理是一次读入 4096(默认)的数据到缓存中,减少多次 syscall 。然后再从缓存中读取需要的数据,不够再从网络测读取。


但是:


  • 没有解决需要 make 导致的 gc 问题

  • 增加了内存复制操作

基于 v5 内存分配器实现的零拷贝 BufReader

v5 的内存分配器看这篇:《Monibuca v5 中实现优雅内存分配器_Go_不卡科技_InfoQ写作社区


基本原理:


  1. 从分配器里面获取一块内存作为缓存

  2. 一次读入一大块数据到缓存中

  3. 缓存中再读取需要的数据,并且可以手动控制回收部分内存


当音视频数据在 ringbuffer 中将要被覆盖的时候,就把对应的内存回收。其他临时的数据(比如长度、时间戳等),都可以在使用完后立即回收。


橘色的内存块是黄色的切片,因此不需要拷贝就能直接使用,在音视频数据的缓存过程中也保持碎片形式,不进行合并操作,在发送的时候使用 writev 批量发送就避免了内存复制。后续可以再结合更底层的网络 IO 库进行进一步的优化底层传输效率。


下面是和 bufio 的 Reader 作一个性能测试对比:


发布于: 刚刚阅读数: 3
用户头像

不卡科技

关注

令人惊叹的流媒体开源项目 2018-04-23 加入

为中小企业提供优质的流媒体开源框架

评论

发布
暂无评论
Monibuca v5 实现零拷贝 BufReader_Go_不卡科技_InfoQ写作社区