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

网站定制论坛关键词搜索爱站网

网站定制论坛,关键词搜索爱站网,符合网络营销网站建设,evernote wordpress基于数组实现的环形缓冲区#xff1a; 优点 使用固定大小的连续空间做用户态缓冲区#xff0c;利用了内存访问的局部性#xff0c;可以提高缓存命中率#xff0c;提高程序性能#xff0c;在处理大量数据时#xff0c;缓存的利用率对性能有着很大的影响 正是基于性能的…基于数组实现的环形缓冲区 优点 使用固定大小的连续空间做用户态缓冲区利用了内存访问的局部性可以提高缓存命中率提高程序性能在处理大量数据时缓存的利用率对性能有着很大的影响 正是基于性能的考虑使用数组做用户态缓冲区同时由于固定的空间大小在使用数组时需要精妙的存取方式另外可以使用stl的vacotr的设计思路动态增长数组的大小这里暂不做实现 先总结一下环形缓冲区ringbuffer的优点 高效的内存管理 环形缓冲区是由一块连续的内存区域组成的这样可以减少内存碎片和内存分配的开销提高内存管理的效率。 预先分配的内存 因为环形缓冲区的大小是固定的所以可以在系统启动时或者初始化时预先分配所需的内存而不需要动态分配内存。这可以避免动态内存分配带来的性能开销和内存碎片问题。 简单的索引计算 由于环形缓冲区的内存布局是连续的所以索引计算非常简单和高效。相比之下可变长链表等数据结构可能需要更复杂的指针操作和内存访问。 更好的缓存性能 环形缓冲区的连续内存布局可以提高缓存的命中率因为它利用了局部性原理使得相关的数据项在内存中更可能是相邻存放的。 代码实现 环形缓冲区结构体 typedef struct ringbuffer_s {uint32_t size; // 缓冲区数组的大小uint32_t tail; // 尾部索引即当前可用的数组位置索引uint32_t head; // 头部索引当前已使用的空间的起始位置索引uint8_t * buf; // 实际缓冲区数组地址 } buffer_t;其中 tail和head索引的设计 考虑到需要确定当前数组的空闲位置以及已使用的位置便于添加新数据和取出数据 创建一个缓冲区 buffer_t * buffer_new(uint32_t sz) { // 结构体和其成员的空间一起分配而不分别分配的原 因是 -- 利用局部性原理提高性能buffer_t * buf (buffer_t *)malloc(sizeof(buffer_t) sz); // 结构体 缓冲区if (!buf) {return NULL;}buf-size sz;buf-head buf-tail 0;buf-buf (uint8_t *)(buf 1); // 可用缓冲区在结构体地址后return buf; }一个缓冲区的初始tail和head索引都是位于数组首部的 一些辅助函数 static uint32_t rb_isempty(buffer_t *r) { // 缓冲区是否为空return r-head r-tail; }static uint32_t rb_isfull(buffer_t *r) { // 缓冲区是否已满return r-size (r-tail - r-head); }static uint32_t rb_len(buffer_t *r) { // 已使用空间return r-tail - r-head; }static uint32_t rb_remain(buffer_t *r) { // 剩余空间return r-size - r-tail r-head; }向缓冲区内添加数据 int buffer_add(buffer_t *r, const void *data, uint32_t sz) {if (sz rb_remain(r)) // 如果剩余空间不足添加失败 return -1;// 如果tail到数组尾部的空间不足以容纳该数据分段添加到尾部和头部uint32_t i;i min(sz, r-size - (r-tail (r-size - 1))); // 计算将填入尾部的空间最大是实际剩余空间// 如果需要分两次填入一部分填入尾部一部分填入头部memcpy(r-buf (r-tail (r-size - 1)), data, i);memcpy(r-buf, datai, sz-i);r-tail (r-tail sz) % r-size; // 更新tail索引可能移动到数组头部return 0; }环形缓冲区的添加操作使用了环绕索引最大限度地利用有限的数组空间 从缓冲区中取出数据 int buffer_remove(buffer_t *r, void *data, uint32_t sz) {assert(!rb_isempty(r)); // 缓冲区为空则移除失败uint32_t i;sz min(sz, r-tail - r-head); // 确保要移除的长度不超过已使用的空间// 根据长度分次从尾部、头部移除i min(sz, r-size - (r-head (r-size - 1)));memcpy(data, r-buf(r-head (r-size - 1)), i);memcpy(datai, r-buf, sz-i);r-head (r-head actual_sz) % r-size; // 更新head可能移动到数组头部return sz; }更新head的索引也用到了环绕的方法 删除一段数据 int buffer_drain(buffer_t *r, uint32_t sz) {if (sz rb_len(r)) // 最多全部删除sz rb_len(r);r-head (r-head sz) % r-size; // 更新索引使用环绕的方法return sz; }获取当前最大可用空间的长度 uint8_t *buffer_write_atmost(buffer_t *r) {uint32_t wpos r-tail;uint32_t rpos r-head;if (wpos rpos) {// Case 1: tail is ahead of or equal to headuint32_t first_chunk r-size - wpos; // Space from tail to end of bufferuint32_t second_chunk rpos; // Space from start of buffer to headreturn r-buf wpos;} else {// Case 2: head is ahead of tailreturn r-buf wpos;}}buffer_write_atmost函数逻辑 如果 tail 在 head 之前即 tail head则从 tail 到 head 之间的空间是可写的大小为 head - tail - 1。如果 tail 在 head 之后即 tail head则从 tail 到缓冲区末尾的空间以及从缓冲区头部到 head 之间的空间都是可写的需要分两段来计算最大可写空间返回 first_chunk second_chunk - 1。 head 之前即 tail head则从 tail 到 head 之间的空间是可写的大小为 head - tail - 1。如果 tail 在 head 之后即 tail head则从 tail 到缓冲区末尾的空间以及从缓冲区头部到 head 之间的空间都是可写的需要分两段来计算最大可写空间返回 first_chunk second_chunk - 1。 至此已经实现了环形缓冲区的创建、添加、删除操作 推荐学习 https://xxetb.xetslk.com/s/p5Ibb
http://www.w-s-a.com/news/814797/

相关文章:

  • 电子网站建设ppt模板营销策划方案怎么写?
  • 什么网站收录排名最高济南能源建设网站
  • 深圳移动网站建设公司价格桂林做网站哪家公司好
  • 互联网网站名字网站合作建设合同
  • 舟山高端网站设计广州优化排名推广
  • 哪个网站做免费广告好上海人才网站
  • cn域名做网站竞价推广代理
  • 省建设干部培训中心网站网站地图1 500 怎么做
  • 制作一个网站需要哪些人网站建设经营服务合同
  • 山东省住房和城乡建设厅官方网站网易发布广州
  • 长沙设计网站效果设计师灵感网站
  • 做网站php都用什么框架把asp.net写的网站别人怎么访问
  • 网站建设捌金手指下拉六正规的代运营公司
  • 自己申请网站空间冀州建网站
  • 哈尔滨旅游团购网站建设江苏建设工程建设网
  • 在郑州做网站茶叶网站建设网页设计制作
  • 58做网站吗南京有关制作网站的公司
  • 申请建设门户网站的申请先做网站还是先申请域名
  • 门户网站怎么做seo玩具外贸好做吗
  • 网页设计模板的网站黄埔营销型网站建设
  • 企业为什么要建立网站江苏高校品牌专业建设工程网站
  • 网站建设公司需要交税么福建省城乡建设厅网站
  • dedecms网站首页网站正在建设中 源码下载
  • 论坛网站有哪些怎么wordpress主题
  • 网站搭建中企动力第一返利的网站怎么做
  • 在哪网站可以做农信社模拟试卷优衣库网站建设的目的
  • 杭州网站建设ttmwl网络平台推广公司
  • 工作室网站技能培训班
  • 东丰网站建设万盛网站制作
  • 安徽黄山网站建设wordpress 公众号 获取密码