(关于Linux读文件的更深入理解, 猛戳这里吧

        在进行大规模数据处理时,读文件很有可能成为速度瓶颈。不管你的CPU有4个核还是8个核,主频有2G还是3G,硬盘IO速度总是有个上限的。在本人最近的一次经历中,对一个11G的文本进行数据处理,一共耗时34.8秒,其中竟然有30.2秒用在访问IO上,占了所有时间的87%左右。
        虽然说硬盘IO是有上限的,那么C++为我们提供的各函数,是否都能让我们达到这个上限呢?为了求得真相,我对这个11G的文本用fread函数读取,在linux下用iostat检查硬盘的访问速度,发现读的速度大约在380M/s。然后用dd指令测了一下读文本的访问速度,发现速度可以达到460M/s。可见单线程fread访问并没有达到硬盘的读取上限。第一次考虑会不会是fread访问硬盘的时候有一些固定开销,用多线程可以达到流水访问IO的效果提高读文本的效率,结果发现多线程也只有380M/s的读取速率。

        为什么fread的效率达不到最大呢?查阅一些资料才知,用fread/fwrite方式访问硬盘,用户须向内核指定要读多少,内核再把得到的内容从内核缓冲池拷向用户空间;写也须要有一个大致如此的过程。这样在访问IO的时候就多经历了这么一个内核的buffer,造成速度的限制。一个解决的办法是mmap。mmap就是通过把文件的某一块内容直接映射到用户空间上,用户可以直接向内核缓冲池读写这一块内容,这样一来就少了内核与用户空间的来回拷贝所以通常更快。


        mmap的使用方法如下:

char *data = NULL;
int fd=open(“file.txt”,O_RDONLY); 
long size = lseek(fd, 0, SEEK_END);
data = (char *) mmap( NULL,  size ,PROT_READ, MAP_PRIVATE, fd, 0 ); 

        这时file.txt文件中的数据就可以从data指针指向的首地址开始访问了。

        为了从数据说明这个问题,我引用一位网友的结论,希望对大家有所启发。


方法/平台/时间(秒)Linux gccWindows mingwWindows VC2008
scanf2.0103.7043.425
cin6.38064.00319.208
cin取消同步2.0506.00419.616
fread0.2900.2410.304
read0.2900.398不支持
mmap0.250不支持不支持
Pascal read2.1604.668

作者:jiang1st

转载此文请注明出处:http://blog.csdn.net/jiang1st2010

GitHub 加速计划 / li / linux-dash
6
1
下载
A beautiful web dashboard for Linux
最近提交(Master分支:4 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐