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

缓存IO与直接IO

IO类型

缓存 I/O

缓存 I/O 又被称作标准 I/O,大多数文件系统的默认 I/O 操作都是缓存 I/O。在 Linux 的缓存 I/O 机制中,数据先从磁盘复制到内核空间的缓冲区,然后从内核空间缓冲区复制到应用程序的地址空间(用户空间)。
读操作:操作系统检查内核空间的缓冲区有没有需要的数据,如果已经缓存了,那么就直接从缓存中返回,也就是将数据复制到应用程序的用户空间;否则从磁盘中读取数据至内核空间的缓冲区,再将内核空间缓冲区的数据返回。
写操作:将数据从用户空间复制到内核空间的缓冲区,这时对用户程序来说写操作就已经完成。至于什么时候将数据从内核空间写到磁盘中,这步由操作系统决定,除非显示地调用了 sync 同步命令。
在这里插入图片描述
缓存 I/O 的优点:
在一定程度上分离了内核空间和用户空间,保护系统本身的运行安全;
可以减少读盘的次数,从而提高性能。

send数据图解

在这里插入图片描述
缓存 I/O 的缺点:存在四次上下文切换(用户态与内核态之间切换),四次数据拷贝(CPU参与), 这些数据拷贝操作所带来的 CPU 以及内存开销是比较大的。CPU参与四次拷贝的计算机好像已经不多见了,内核到磁盘的数据拷贝更多的是采用DMA。

如果采用DMA的IO完整流程图:

在这里插入图片描述
这里还是发生了 4 次用户态与内核态的上下文切换,发生了 4 次数据拷贝,但其中两次是 CPU参与的拷贝,降低了CPU压力。

直接 I/O

Linux提供了对这种需求的支持,即在open()系统调用中增加参数选项O_DIRECT,用它打开的文件便可以绕过内核缓冲区的直接访问,这样便有效避免了CPU和内存的多余时间开销。顺便提一下,与O_DIRECT类似的一个选项是O_SYNC,后者只对写数据有效,它将写入内核缓冲区的数据立即写入磁盘,将机器故障时数据的丢失减少到最小,但是它仍然要经过内核缓冲区
在这里插入图片描述


#include <stdio.h>  
#include <stdlib.h>  
#include <fcntl.h>  
#include <unistd.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
#include <sys/mman.h>  
#include <string.h>  #define FILE_SIZE 4096  // 假设文件大小为4KB,为了示例简单  
#define BLOCK_SIZE 512  // 假设块大小为512B  int main() {  int fd;  char *buffer;  off_t offset = 0;  ssize_t bytes_read, bytes_written;  // 打开文件,使用O_DIRECT和O_SYNC标志  fd = open("testfile", O_RDWR | O_CREAT | O_TRUNC | O_DIRECT | O_SYNC, 0644);  if (fd == -1) {  perror("open");  exit(1);  }  // 分配内存对齐的缓冲区  // 注意:直接I/O要求缓冲区是块大小的整数倍,并且内存对齐到块大小的边界  posix_memalign((void **)&buffer, BLOCK_SIZE, FILE_SIZE);  if (buffer == NULL) {  perror("posix_memalign");  close(fd);  exit(1);  }  // 写入文件  memset(buffer, 'A', FILE_SIZE);  // 填充数据  bytes_written = pwrite(fd, buffer, FILE_SIZE, offset);  if (bytes_written != FILE_SIZE) {  perror("pwrite");  free(buffer);  close(fd);  exit(1);  }  // 重置偏移量以进行读取  offset = 0;  // 读取文件  bytes_read = pread(fd, buffer, FILE_SIZE, offset);  if (bytes_read != FILE_SIZE) {  perror("pread");  free(buffer);  close(fd);  exit(1);  }  // 打印读取的数据(可选)  // ...  // 清理  free(buffer);  close(fd);  return 0;  
}
注意:对齐问题:直接I/O要求缓冲区在内存中是块大小的整数倍,并且从块大小的边界开始。在上面的示例中,我们使用posix_memalign来分配内存对齐的缓冲区。
文件大小:为了简单起见,上面的示例假设文件大小为4KB,并且块大小为512B。在实际应用中,你可能需要处理更大的文件和/或不同的块大小。
错误处理:在生产代码中,你应该更详细地处理错误情况,并为用户提供有用的错误消息。
性能考虑:虽然直接I/O可以提高性能,但它也可能增加复杂性,并可能不适用于所有用例。在决定使用它之前,请确保你了解其优点和缺点。
内核参数:在某些情况下,你可能需要调整内核参数来启用或优化直接I/O。例如,/proc/sys/vm/dirty_bytes、/proc/sys/vm/dirty_background_bytes等参数可能会影响直接I/O的性能。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 基于51单片机的数字频率计(电路图+pcb+论文+仿真+源码)
  • hyperf 多对多关联模型
  • 智能化让幼儿园管理更加规范
  • world machine学习笔记(3)
  • 方正畅享全媒体新闻采编系统 binary.do SQL注入漏洞复现
  • 智能家居6 -- 配置 ini文件优化设备添加
  • 【C++】详解AVL树——平衡二叉搜索树
  • 电商公司需不需要建数字档案室呢
  • 下一代Docker会让部署更丝滑吗
  • 说些什么好呢
  • 鸿蒙系统和安卓系统通过termux搭建Linux系统—Centos
  • 常见算法(3)
  • AI爆文写作:或许开放性的标题,才会更让人想点开了解答案
  • easy-es EsAutoConfiguration RestHighLevelClient 没有自动注入配置
  • 算法训练营第三十九天 | LeetCode 738 单调递增的数字、LeetCode 968 监控二叉树
  • 【Under-the-hood-ReactJS-Part0】React源码解读
  • 2017 前端面试准备 - 收藏集 - 掘金
  • 345-反转字符串中的元音字母
  • FineReport中如何实现自动滚屏效果
  • hadoop集群管理系统搭建规划说明
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • Intervention/image 图片处理扩展包的安装和使用
  • JavaScript DOM 10 - 滚动
  • Javascript 原型链
  • Lucene解析 - 基本概念
  • SQL 难点解决:记录的引用
  • Vue2.x学习三:事件处理生命周期钩子
  • vue-router的history模式发布配置
  • webpack项目中使用grunt监听文件变动自动打包编译
  • 闭包,sync使用细节
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • 实现菜单下拉伸展折叠效果demo
  • 我与Jetbrains的这些年
  • [Shell 脚本] 备份网站文件至OSS服务(纯shell脚本无sdk) ...
  • ​sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块​
  • # 安徽锐锋科技IDMS系统简介
  • # 日期待t_最值得等的SUV奥迪Q9:空间比MPV还大,或搭4.0T,香
  • #Datawhale AI夏令营第4期#AIGC文生图方向复盘
  • (Java实习生)每日10道面试题打卡——JavaWeb篇
  • (Note)C++中的继承方式
  • (九)One-Wire总线-DS18B20
  • (强烈推荐)移动端音视频从零到上手(下)
  • (三十五)大数据实战——Superset可视化平台搭建
  • (实测可用)(3)Git的使用——RT Thread Stdio添加的软件包,github与gitee冲突造成无法上传文件到gitee
  • (太强大了) - Linux 性能监控、测试、优化工具
  • (转)Linux NTP配置详解 (Network Time Protocol)
  • (转)socket Aio demo
  • ***测试-HTTP方法
  • ***汇编语言 实验16 编写包含多个功能子程序的中断例程
  • .mat 文件的加载与创建 矩阵变图像? ∈ Matlab 使用笔记
  • .net 8 发布了,试下微软最近强推的MAUI
  • .net6 当连接用户的shell断掉后,dotnet会自动关闭,达不到长期运行的效果。.NET 进程守护
  • .vue文件怎么使用_vue调试工具vue-devtools的安装
  • @Bean, @Component, @Configuration简析