使用C ++随机读取大文件时减速

时间:2016-06-15 15:28:31

标签: c++ file memory io

在整个大文件(> 4GB)的随机位置读取数据块时遇到了一些麻烦。
任务是将3D数据立方体保存到文件并转置轴,而不将整个数据集加载到RAM中 存储格式如下:
我在文件的开头有3个整数,存储尺寸(nX,nY,nZ) 之后,数据为长度为nX的行 这些行重复nY次,这导致页面并且页面重复nZ次 含义:
一行有nX个字节
页面有nX * nY个字节
该文件有nX * nY * nZ + 12个字节
要转置数据集,我执行以下循环:

for( int i=0;i<nY;i++ )
{
    for( int j=0;j<nZ;j++ )
    {
        read( pBuf, i*nX+j*nY*nX );//read nX bytes from offset i*nX+j*nX*nY
        writeNext(pBuf);
    }
}

当使用fopen,_fseeki64和fread它发生在大约。每6次读取的总读数的30%需要长达7秒,因为有数百万次读取我不能接受这些延迟。 因此,我使用内存映射文件(CreateFile,CreateFileMapping和MapViewOfFile)实现了相同的算法,但现在每6次读取大约需要2秒。
有没有提高读出速度的方法/机会?

EDIT1:
我在http://pastebin.com/MejiTKj0添加了一些代码 EDIT2:
有些人可能会注意到读取函数中的偏移量不一致。为了简化问题,我没有告诉文件头中保存的所有变量,因此15个字节的偏移是可以的

3 个答案:

答案 0 :(得分:0)

如果您有一个存储文件的HDD磁盘,您应该知道在尝试执行随机访问时,搜索时间占主导地位。您可能会发现最好将整个文件按顺序读入内存(与搜索相比,操作相对较快),然后对内存数据执行处理。即使您只需要相对较小比例的整体文件数据,您也会发现这样更快。

答案 1 :(得分:0)

在循环中,Z / nZ应该是最外圈,Y应该是内循环。如果存储内存布局逐个存储了nZ页,那么这将节省寻道时间。

在显示的当前代码中,它在内循环中显示nZ,这是不好的。循环的当前排列类似于书籍阅读,读取书籍每页的第一行,然后读取第二行等等;

答案 2 :(得分:0)

非常感谢您的投入。 实际上,我应该检查的第一件事是错误的,就是HDD,它无法提供所需的数据速率。
我现在正在考虑切换到SSD - 设备。