从fread和mmap谈C++读文件的性能

来源:互联网 发布:航班动态查询软件 编辑:程序博客网 时间:2024/05/29 09:40
(关于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 VC2008scanf2.0103.7043.425cin6.38064.00319.208cin取消同步2.0506.00419.616fread0.2900.2410.304read0.2900.398不支持mmap0.250不支持不支持Pascal read2.1604.668
作者:jiang1st

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

原创粉丝点击