mmap为什么比read/write快(兼论buffercache和pagecache)
参考文献:
《从内核文件系统看文件读写过程》http://www.cnblogs.com/huxiao-tee/p/4660352.html?utm_source=tuicool&utm_medium=referral
《mmap是什么》http://www.cnblogs.com/huxiao-tee/p/4660352.html?utm_source=tuicool&utm_medium=referral
正文:
首先说一下文件系统,Linux文件系统的三层结构想必大家多少都了解一些,每个进程中都有一个用户文件描述符表,表项指向一个全局的文件表中的某个表项,文件表表项有一个指向内存inode的指针,每个inode唯一标识一个文件。如果同时有多个进程打开同一文件,他们的用户文件描述符表项指向不同的文件表项,但是这些文件表项会指向同一个inode。
此时又会引出另外一个东东:page cache。内核会为每个文件单独维护一个page cache,用户进程对于文件的大多数读写操作会直接作用到page cache上,内核会选择在适当的时候将page cache中的内容写到磁盘上(当然我们可以手工fsync控制回写),这样可以大大减少磁盘的访问次数,从而提高性能。Page cache是linux内核文件访问过程中很重要的数据结构,page cache中会保存用户进程访问过得该文件的内容,这些内容以页为单位保存在内存中,当用户需要访问文件中的某个偏移量上的数据时,内核会以偏移量为索引,找到相应的内存页,如果该页没有读入内存,则需要访问磁盘读取数据。为了提高页得查询速度同时节省page cache数据结构占用的内存,linux内核使用树来保存page cache中的页。
在了解了以上的基础之后,我们就来比较一下mmap和read/write的区别,先说一下read/write系统调用,read/write系统调用会有以下的操作:
- 访问文件,这涉及到用户态到内核态的转换
- 读取硬盘文件中的对应数据,内核会采用预读的方式,比如我们需要访问100字节,内核实际会将按照4KB(内存页的大小)存储在page cache中
- 将read中需要的数据,从page cache中拷贝到用户缓冲区中
整个过程还是比较艰辛的,基本上涉及到用户内核态的切换,还有就是数据拷贝接下来继续说mmap吧,mmap系统调用是将硬盘文件映射到用内存中,说的底层一些是将page cache中的页直接映射到用户进程地址空间中,从而进程可以直接访问自身地址空间的虚拟地址来访问page cache中的页,这样会并涉及page cache到用户缓冲区之间的拷贝,mmap系统调用与read/write调用的区别在于:
- mmap只需要一次系统调用,后续操作不需要系统调用
- 访问的数据不需要在page cache和用户缓冲区之间拷贝
从上所述,当频繁对一个文件进行读取操作时,mmap会比read高效一些。
最后再说一下page cache的话题,从上面所说我们从磁盘文件中读取的内容都会存在page cache中,但当我们关闭这个文件时,page cache中内容会立马释放掉吗?答案是否,磁盘的读取速度比内存慢太多,如果能命中page cache可以显著提升性能,万一后续又有对这个文件的操作,系统就可以很快速的响应。当然,这些文件内容也不是一直存在page cache中的,一般只要系统有空闲物理内存,内核都会拿来当缓存使用,但当物理内存不够用,内存会清理出部分page cache应急,这也就是告诉我们程序对于物理内存的使用能省则省,交给内核使用,作用很大。
还有就是普通的write调用只是将数据写到page cache中,并将其标记为dirty就返回了,磁盘I/O通常不会立即执行,这样做的好处是减少磁盘的回写次数,提供吞吐率,不足就是机器一旦意外挂掉,page cache中的数据就会丢失。一般安全性比较高的程序会在每次write之后,调用fsync立即将page cache中的内容回写到磁盘中。
mmap为什么比read/write快(兼论buffercache和pagecache)的更多相关文章
- pcl点云文件格式
PCD版本 在点云库(PCL)1.0版本发布之前,PCD文件格式有不同的修订号.这些修订号用PCD_Vx来编号(例如,PCD_V5.PCD_V6.PCD_V7等等),代表PCD文件的0.x版本号.然而 ...
- 点云格式-pcd
每一个pcd文件包含一个文件头,它声明文件中存储的点云数据的特性(元数据).pcd文件头必须用ASCII码来编码.头文件属性字段都以一个新行(\n)分开.从0.7版本开始,pcd文件头包含下面的字段: ...
- Word2Vec的基本使用
目录 1.建立模型 2.保存与加载模型 3.使用模型 gensim 是 Python 中一款强大的 自然语言处理工具,它包含了常见的模型,其中便有 Word2Vec 这一优秀的 词向量训练工具,可以使 ...
- PCL的学习必要性、重要性、意义及最初——持续修改中
为什么学习PCL:图像描述:各种维度图像的逻辑描述形式 ^-^ 且点云库是机器人学领域的必备基础库,ICRA和IROS的计算机视觉相关一般都使用了PCL库,PCL库也成为ROS的基础部分,与机器人操 ...
- PCD(点云数据)文件格式
博客转载自:http://www.pclcn.org/study/shownews.php?lang=cn&id=54 为什么用一种新的文件格式? PCD文件格式并非白费力气地做重复工作,现有 ...
- 顺序、随机IO和Java多种读写文件性能对比
概述 对于磁盘的读写分为两种模式,顺序IO和随机IO. 随机IO存在一个寻址的过程,所以效率比较低.而顺序IO,相当于有一个物理索引,在读取的时候不需要寻找地址,效率很高. 基本流程 总体结构 我们编 ...
- linux内存源码分析 - 零散知识点
本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 直接内存回收中的等待队列 内存回收详解见linux内存源码分析 - 内存回收(整体流程),在直接内存回收过程中, ...
- linux程序员的proc文件系统
1) 设置core文件存放路径和文件名模式: 设置/proc/sys/kernel/core_pattern,如: echo "core" > /proc/sys/kerne ...
- 高效IO解决方案-Mmap「给你想要的快」
随着技术的不断进步,计算机的速度越来越快.但是磁盘IO速度往往让欲哭无泪,和内存中的读取速度有着指数级的差距:然而由于互联网的普及,网民数量不断增加,对系统的性能带来了巨大的挑战,系统性能往往是无数技 ...
随机推荐
- 使用App.config管理数据库连接
程序的数据库连接字符串可以保持在程序的配置文件App.config中,便于管理. 将配置文件添加至解决方案: 添加连接信息: <?xml version="1.0"?> ...
- console的花式用法
1.百度的招聘启示 如图: 下面是输出代码: if(window.console){ var cons = console; if(cons){ cons.log("%c\n ", ...
- iTestSharp的简单应用
前言 最近公司某项目要针对一些信息基础表绘画成表格的形式然后生成pdf文件,在网上寻找到iTestSharp发现此类库很强大,虽然园子里已经有很多大牛写了关于此插件的使用方法,但是自己也想写一写,把自 ...
- 织梦DedeCMS
DedeAMPZ服务器套件 http://dedeampz.dedecms.com/ DedeCMS PHP开源网站管理系统 CMS系统 http://www.dedecms.com/produc ...
- 用rose画UML图(用例图,活动图)
用rose画UML图(用例图,活动图) 首先,安装rose2003,电脑从win8升到win10以后,发现win10并不支持rose2003的安装,换了rose2007以后,发现也不可以. 解决途径: ...
- CentOS 7 配置虚拟主机站点
1.进入/etc/httpd/conf 下 将httpd.conf 打开. 2.将DocumentRoot注释掉.(将ServerName 打开要不会有错误警告). 3.将虚拟主机站点配置包含进来:I ...
- VPS服务商
1.vpsee http://www.vpsee.com 2.vps侦探 http://www.vpser.net/
- Linux磁盘分区及配额123
实验目的: 在现有磁盘的基础上进行分区格式化并为特定用户实施磁盘配额,使其对磁盘这一分区的写入有一定的限制 前期准备: 在我的虚拟机rhel7上有/dev/sda这一分区和fsy这一用户,我将对/de ...
- React项目(二):生命游戏
引子 这是16年最后的一个练手项目,一贯的感觉就是,做项目容易,写说明文档难.更何况是一个唤起抑郁感觉的项目,码下的每个字,心就如加了一个千斤的砝码. 2016年,有些事我都已忘记,但我现在还记得.2 ...
- 第二章 --- 关于Javascript 设计模式 之 策略模式
这一章节里面,我们会主要的针对JavaScript中的策略模式进行理解和学习 一.定义 策略模式: 定义一系列的算法,把他们封装起来,并且是他们可以相互替换. (这样的大的定义纲领,真的不好理解,特别 ...