从fread和mmap谈C++读文件的性能
linux-dash
A beautiful web dashboard for Linux
项目地址:https://gitcode.com/gh_mirrors/li/linux-dash
免费下载资源
·
(关于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的读取速率。
这时file.txt文件中的数据就可以从data指针指向的首地址开始访问了。
作者:jiang1st
在进行大规模数据处理时,读文件很有可能成为速度瓶颈。不管你的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 gcc | Windows mingw | Windows VC2008 |
scanf | 2.010 | 3.704 | 3.425 |
cin | 6.380 | 64.003 | 19.208 |
cin取消同步 | 2.050 | 6.004 | 19.616 |
fread | 0.290 | 0.241 | 0.304 |
read | 0.290 | 0.398 | 不支持 |
mmap | 0.250 | 不支持 | 不支持 |
Pascal read | 2.160 | 4.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 年前
更多推荐
已为社区贡献3条内容
所有评论(0)