当前位置: 首页 > ds >正文

Ring Buffer解析

Ring Buffer,即环形缓冲区,也称作环形队列,是一种用于表示一个固定尺寸、头尾相连的缓冲区的数据结构,适合缓存数据流。

结构与原理

环形缓冲区通常使用一个固定大小的数组作为底层结构,并通过两个指针来管理数据的读写位置,即读指针和写指针。当写指针到达缓冲区末尾时,会自动回绕到缓冲区的起始位置,继续写入数据,从而形成一个环形的存储结构。读指针的移动方式与之类似,当读取完缓冲区末尾的数据后,会回到起始位置继续读取。

特点

  • 高效空间复用:环形缓冲区写满后继续回绕,无需频繁申请和释放内存,具有高效空间复用性,且顺序访问性能好,适合嵌入式与内核编程。
  • 数据顺序性:它是一种先进先出(FIFO)的数据结构,当一个数据元素被读取出后,其余数据元素不需要移动其存储位置。
  • 固定容量:缓冲区的容量一般固定,适合于事先明确了缓冲区最大容量的情形,若缓冲区大小需要经常调整,用链表实现更为合适。

状态判断

判断环形缓冲区的空满状态是一个关键问题。常见的方法有以下两种:

  • 镜像指示位方法:规定读写指针的地址空间为 0 至 2n-1,其中 n 为缓冲区长度,低半部分对应常规逻辑地址空间,高半部分为镜像逻辑地址空间。用一位表示写指针或读指针是否进入镜像存储区,若读写指针的值相同且指示位相同,说明缓冲区为空;若二者指示位不同,说明缓冲区为满。
  • 位运算方法:如果缓冲区长度是 2 的幂,可以省略镜像指示位。若读写指针的值相等,则缓冲区为空;若读写指针相差 n,则缓冲区为满,这可以用条件表达式(写指针 == (读指针异或缓冲区长度))来判断。

接收缓存区

  • 结构与原理:网卡接收缓存区通常采用环形缓冲区(Ring Buffer)结构。驱动程序会先在内存中创建一个接收描述符环(rx descriptor ring),并将其总线地址写入网卡寄存器。每个描述符对应一个用于存储数据包的缓冲区(如 sk_buff),通过流式 DMA 映射将缓冲区的总线地址保存到描述符中。当网卡接收到数据包时,会先将数据写入自身的 FIFO 缓冲区,然后 DMA 通过 PCI 总线将 FIFO 中的数据包复制到描述符指向的数据缓存区。复制完成后,网卡会向 CPU 发起硬件中断,通知有新的数据包到达,CPU 则执行中断处理函数,将数据从缓存区取出并交给上层网络栈处理。
  • 作用:当设备的 CPU 繁忙时,端口不能立即将收到的报文交给 CPU 处理,接收缓存区可以将数据暂时存储起来,避免数据丢失。

发送缓存区

  • 工作流程:应用程序通过系统调用将数据放入 socket 的发送缓冲区,网络协议栈从发送缓冲区中取出数据,添加各种头部信息后,触发软件中断通知网卡驱动程序。网卡驱动程序再将数据写到发送缓存区(如 ringbuffer),由网卡负责从缓存区中读取数据并发送到网络上。发送成功后,网卡会触发硬件中断,释放相关的缓存资源。
  • 作用:当网络拥塞时,端口不能立即发送数据,发送缓存区可以将数据暂时存储,防止数据丢失。

相关配置与调优

  • 缓存区大小调整:可以通过相关工具(如 ethtool)调整接收和发送缓存区的大小。一般来说,缓存区队列越大,丢包的可能性越小,但数据延迟会增加。
  • 多队列处理:在多核 CPU 环境下,网卡内部可能有多个 Ring Buffer,支持 Receive Side Scaling(RSS)或 multiqueue 功能,NIC 会根据一个 Hash 函数对收到的数据包进行分发,将数据分配给不同的 CPU 核心处理,提高数据的并行处理能力。

参考链接:ring buffer,一篇文章讲透它? - +liang - 博客园

http://www.xdnf.cn/news/19570.html

相关文章:

  • 仓颉语言Web框架中的路由分组
  • linux系统学习(6.软件包管理)
  • 十分钟快速掌握 YML YAML 文件
  • 07.《交换机三层功能、单臂路由与端口安全基础知识》
  • 在Linux环境安装Maven(保姆级别)
  • leetcode 面试题 01.01.判定字符是否唯一
  • 【高级】系统架构师 | 信息系统基础
  • 基于Seurat的空转单样本数据分析流程学习(一)
  • JavaScript中的XMLHttpRequest对象分析
  • 基于单片机智能保温杯/智能水杯
  • Java基础第7天总结(代码块、内部类、函数式编程)
  • 【多模态】使用LLM生成html图表
  • 打开多个Excel文件后快速关闭所有的文档,并且退出Excel应用
  • s[:] = reversed(s) 和 s = reversed(s)的区别
  • 【Proteus仿真】点亮小灯系列仿真——小灯闪烁/流水灯/交通灯
  • R3:适用于 .NET 的新一代响应式扩展库,事件订阅流
  • TFS-2002《Fuzzy Clustering With Viewpoints》
  • 嵌入式ARM程序高级调试技能:19.qumu arm elf无法生成coredump
  • 接口测试:如何定位BUG的产生原因
  • nginx-增加VTS模块
  • 数据结构八股
  • 数据结构(C语言篇):(八)栈
  • vscode+EIDE+Clangd环境导入keil C51以及MDK工程
  • shell脚本第六阶段---三剑客之sed
  • C++日志系统:高效异步日志实现解析
  • LeetCode 36. 有效的数独 - 解题思路与实现详解
  • ans.1中的对象标识符OBJECT_IDENTIFIER----OID
  • 【机器学习基础】决策树算法原理及其在无人驾驶技术中的应用
  • Matplotlib:让数据在Python中跳舞的魔法画笔![特殊字符]
  • 基于FPGA的正弦波和及滤波(已通过仿真和上板)