前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Monibuca v5 实现零拷贝 BufReader

Monibuca v5 实现零拷贝 BufReader

作者头像
我不是码神
发布2024-04-23 08:10:36
1200
发布2024-04-23 08:10:36
举报
文章被收录于专栏:流媒体技术流媒体技术

背景

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

直接读取

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

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

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

使用 bufio.Reader

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

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

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

但是:

  1. 没有解决需要 make 导致的 gc 问题
  2. 增加了内存复制操作

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

v5 的内存分配器看这篇:《

李宇翔:m7s v5 中实现优雅内存分配器

基本原理:

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

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

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

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

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

下面是和 bufio 的 Reader 做一个性能对比:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-04-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
    • 直接读取
      • 使用 bufio.Reader
      • 基于 v5 内存分配器实现的零拷贝BufReader
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档