操作系统-内存缓冲区带来了什么好处

前言

不知道大家是否有过这样的疑惑,为什么读写文件时通常需要开辟一块内存缓冲区?内存缓冲区为何能够提升文件读写的效率?其实这一类问题都可以归入到操作系统中,接下来请跟随我的脚步,为大家揭秘背后的原理。

原理

首先我们要知道操作系统对各种硬件资源提供了虚拟化。例如操作系统通过时钟机制和轮询调度让一个CPU看起来像是分身成了多个CPU一样,以及原本是共享介质的内存也因为操作系统的虚拟化能够让每个进程独占内存,让进程只能访问自己的内存地址空间。通过虚拟化硬件,上层的用户可以方便的操控这些资源,同时系统资源的利用率和安全也得到了保障。磁盘也不例外,操作系统也对它进行了虚拟化,在其基础上虚拟出了文件系统、块等概念,今天我们要探讨的便是其中的文件块。

操作系统访问磁盘并不是一个字节一个字节的访问,所以不能得出如果一个文件有5个字符,那么它的磁盘访问耗时就是5s这样的结论(假设一次磁盘访问时间是1s)。操作系统访问磁盘的基本单位是文件块,是一个块一个块的访问,所以读写文件所产生的磁盘访问耗时大小是依赖于文件块的大小。例如系统中的文件块大小是4kb,那么读/写1b-4kb数据所产生的磁盘访问耗时都是1s。因此我们可以得出以下两个公式:

1.直接读/写磁盘时:

磁盘访问耗时=(读/写次数*(一次磁盘访问时间*n))

2.使用缓冲区读/写磁盘时:

磁盘访问耗时=(读/写次数一次内存访问时间)+(一次磁盘访问时间n)

(其中n为文件所占用的文件块的个数)

有了上述的两个公式,相信能够很容易的计算出磁盘访问耗时。假设系统中的文件块大小是4kb,一次内存访问时间是0.5s,一次磁盘访问时间是1s,给定一个要读取的大小50字节的文件b,每次读取10字节,请问直接读取完文件b和采用内存缓冲区读取完文件b分别所产生的磁盘访问耗时是多少呢?没错,答案就是5s(5s=5*(1s1))和3.5s(3.5s=50.5s+1s*s)。通过结果明显可以看出内存缓冲区所带来的的高效率了吧。

实践

准备工作:

1.用于计算读取文件耗时的c程序:

arduino 复制代码
#include<stdio.h>
#include<stdlib.h>
#include<sys/time.h>
#include<unistd.h>
#include<fcntl.h>


int main(){
  struct timeval starttv,endtv;
  long sum=0;
  int n,size;
  char* fname=(char*)malloc(sizeof(char) * 100);;
  printf("实验次数: ");
  scanf("%d", &n);
  printf("请输入缓冲区大小: ");
  scanf("%d", &size);
  printf("请输入要读取的文件名: ");
  scanf("%s", fname);
  FILE *fp = fopen(fname,"r");
  for(int i=0;i<n;i++){
      char buffer[size];
      int readByte = 0;
      gettimeofday(&starttv,NULL);
      long startTime = starttv.tv_sec*1000*1000+starttv.tv_usec;
      while((readByte=fread(buffer,sizeof(char),sizeof(buffer),fp))>0){

      }
     gettimeofday(&endtv,NULL);
     long endTime = endtv.tv_sec*1000*1000+endtv.tv_usec;
     sum+=endTime-startTime;
     fseek(fp, 0L, SEEK_SET);
  }
  fclose(fp);
  printf("磁盘访问耗时:%f微秒\n",(float)(sum)/n);
  return 0;
}

实践证明1:操作系统访问磁盘的基本单位是文件块(4kb),读/写1字节所产生的耗时和读/写4096字节产生的耗时是相同的。

1.准备好三个文件a.txt(4096字节),b.txt(1字节),c.txt(4097字节)。

2.查看系统的文件块大小stat -c '%o' 文件名,可以看见块大小为4kb

3.调用测量程序计算读取a.txt和b.txt的磁盘耗时,双方耗时都是0.7微秒左右,即读/写1字节所产生的耗时和读/写4096字节产生的耗时是相 同的。

4.调用测量程序计算读取a.txt和c.txt的磁盘耗时,a.txt耗时0.7微秒,c.txt耗时1微秒。仅仅相差了一个字节就多出了这么多耗时,这是因为c.txt占用两个文件块,而a.txt只占用了一个块,同时也能看出操作系统访问磁盘的基本单位是文件块(4kb)。

实践证明2:使用内存缓冲区访问磁盘的效率高于直接访问磁盘

1.准备一个文件a.txt(4096字节)

2.调用测量程序,设置缓冲区大小为1(模拟不使用内存缓冲区,逐字节读取),耗时达到了惊人的37微秒!

3.调用测量程序,设置缓冲区大小为4096,效率大幅提升

总结

操作系统访问磁盘的基本单位是文件块,数据大小在一个文件块的范围内的文件产生的磁盘耗时都是相同的,通过内存缓冲区我们可以一次从磁盘中读取多个字节,提升程序性能。既然一次读1个字节磁盘耗时是1s,一次读100个字节磁盘耗时也是1s,那我们为什么不选择使用内存缓冲区一次读100个字节呢。

相关推荐
修修修也20 小时前
【Linux】进程间通信
linux·运维·服务器·操作系统·进程通信
Pandaconda3 天前
【操作系统】每日 3 题(十八)
linux·服务器·开发语言·数据结构·笔记·后端·操作系统
vincent_woo3 天前
再学安卓 - 系统环境安装
操作系统
Raymond运维3 天前
第一章 Linux安装 -- 安装Debian 12操作系统(四)
linux·运维·服务器·操作系统·debian
小蜗的房子3 天前
一篇文章让你了解Linux中的用户和组权限
linux·运维·服务器·后端·学习·操作系统·基础
简鹿办公4 天前
Windows 怎么关机?这五种方法你需要了解一下
操作系统
星海幻影4 天前
linux基础-完结(详讲补充)
linux·服务器·网络·安全·操作系统
小林up5 天前
【MIT-OS6.S081笔记1】Chapter1阅读摘要:Operating system interfaces
笔记·操作系统
linhhanpy5 天前
自制操作系统(九、操作系统完整实现)
c语言·开发语言·汇编·c++·操作系统·自制操作系统
tt5555555555556 天前
操作系统学习笔记-5.1-IO设备
服务器·笔记·嵌入式硬件·学习·操作系统