mmap为什么比read快
参考文献:
《从内核文件系统看文件读写过程》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快相关推荐
- 【linux】为什么 mmap 比系统调用快
1.概述 翻译:Why mmap is faster than system calls 当我问我的同事为什么 mmap 比系统调用更快时,答案不可避免地是"系统调用开销":跨越用 ...
- C++“读取“大量数据时--快读
在一些算法题目中中,有的程序会被卡常数,就是说,程序虽然时间复杂度可以接受,但因为算法本身的时间常数过大,导致程序在一些算法竞赛中超时.这是,快读就显得尤为重要了. 当然,如果程序算法本身就不高效,快 ...
- 重新认识 Java 中的内存映射(mmap)
mmap 基础概念 mmap 是一种内存映射文件的方法,即将一个文件映射到进程的地址空间,实现文件磁盘地址和一段进程虚拟地址的映射.实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而 ...
- linux系统提升硬盘写速度的方法
LINUX系统写速度问题解决过程 问题描述: linux系统下写速度只有2GB/s左右,无法支持2.5G采样率连续采集,达不到预期的性能.而同样的代码在windows系统下,却可以支持2.5G采样率连 ...
- RocketMQ4.X消息队列详细笔记
人不能没有批评和自我批评 那样一个人就不能进步. 目录 JMS和消息中间件介绍 JMS消息服务和使用场景 消息中间件常见概念和编程模型 主流消息队列和技术选型讲解 基础介绍和阿里云服务器快速部署 Ro ...
- RocketMQ学习笔记(二)
第六章 RocketMQ生产者核心配置和核心知识讲解 第1集 消息队列RocketMQ4.X生产者核心配置讲解 简介:消息队列RocketMQ4.X核心配置讲解 生产者常见核心配置 compressM ...
- 抖音品质建设 - iOS启动优化《实战篇》
前言 启动是 App 给用户的第一印象,启动越慢,用户流失的概率就越高,良好的启动速度是用户体验不可缺少的一环.启动优化涉及到的知识点非常多,面也很广,一篇文章难以包含全部,所以拆分成两部分:原理和实 ...
- RocketMQ源码级别面试题板块
目录 事务消息篇 消费者端 Broker端 面试题版块 Kafka版块 Kafka生产消息为什么快之PageCache kafka的生产者和消费者如何借助Pagecache实现快速读和快速写 Kafk ...
- rocketMQ-消息队列
RocketMQ4.X基础介绍 官网地址 http://rocketmq.apache.org/ 参考资料 http://jm.taobao.org/2017/01/12/rocketmq-quick ...
- 讲一讲什么是 MMAP
1. mmap 基础概念 mmap 即 memory map,也就是内存映射. mmap 是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一 ...
最新文章
- R语言绘制堆叠的环状条形图
- 新手java五子棋完整代码判断落子落在线上_Java初学者,编写小游戏五子棋的问题?...
- DFS与BFS的总结
- 怎么查看电脑配置参数linux,linux下查看电脑配置
- [Swift]LeetCode45. 跳跃游戏 II | Jump Game II
- 原生JS forEach()和map()遍历的区别以及兼容写法
- Google DeepMind围棋程序AlphaGo的分析
- Scala集合常用方法:reduceLeft/reduceRight
- linux删除目录是显示非空,Linux删除非空目录
- delphi基本语法
- Codeforces Round #280 (Div. 2)
- oracle导出dmp空表导不出来,如何解决Oracle11g使用dmp命令无法导出空表问题
- 4g模块注册上网 移远_物联网模组龙头移远通信
- matlab信息量估计法估计嵌入率,LSB密写分析-信息量估计法
- 【Matlab】建立最优控制LQR控制器模型
- html嵌入word文档,网页中嵌入word文档和导出数据到word文档
- 袖珍磁带的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
- (专升本)PowerPoint(设置幻灯片的动画效果)
- Amazon,我们完全不能接受 — 因此我们必须变更 Elastic 许可协议
- BZOJ 2144 跳跳棋
热门文章
- ICSharpCode.SharpZipLib实现压缩解压缩
- gbdt 算法比随机森林容易_数据挖掘面试准备(1)|常见算法(logistic回归,随机森林,GBDT和xgboost)...
- Hadoop 开源调度系统zeus
- jqgrid 点击列头的超链接或按钮时,不触发列排序事件
- 《R数据可视化手册》——2.5 绘制箱线图
- C# string byte[] Base64 常用互相转换
- jdbc 连接oracle 数据库格式
- 迁移 Linux 系统,第 1 部分——如何迁移备份和裸机恢复 Linux 系统
- mysql慢查询优化
- 搞定机器学习面试,这些是基础!