稀疏读取50gb文件

时间:2014-09-24 01:53:04

标签: c++

我有一个50gb的文件,我想读。

将从50gb文件中读取x指令。它们将按顺序排列,但位置不可预测。每条指令将读取1个字节。

总读数占<文件总大小的0.0000001%,可能总共大约100个字节。

现在我正在使用带偏移的seekg来执行此操作,但它正在采取>有时3秒。

在这种情况下,内存映射文件会加快读取速度吗?如果我没有50gb的ram,那么记忆映射文件是否有意义?

我还能做些什么来加快速度吗?

以下是一些代码,需要大约2秒才能为我运行(我将其调整为300次读取以使其花费更长时间):

#include <iostream>
#include <fstream>
#include <set>
#include <cstdlib>

using namespace std;

int main() {

    ifstream in("E:/t.dat", ifstream::binary);
    in.rdbuf()->pubsetbuf(0, 1);
    set<long long> S;
    srand(time(NULL));
    for(int i=0;i<300;i++){
        S.insert((long long)(rand()%50000000)*1000ll);

    }

    long long offset = 0;
    in.seekg(0,ios::beg);
    int sum = 0;
    for(set<long long>::iterator it = S.begin(); it!=S.end(); it++){
        long long toseek = *it - offset;
        while(toseek > 2000000000){
            in.seekg(2000000000,ios::cur);
            toseek -= 2000000000;
            offset += 2000000000;
        }
        in.seekg(toseek,ios::cur);
        offset += toseek;
        char c;
        in.read(&c,1);
        offset++;
        sum += (int)c;
    }
    cout<<sum<<endl;
}

2 个答案:

答案 0 :(得分:4)

  

在这种情况下,内存映射文件是否会加快读取速度?

如果不了解有关文件访问模式和操作系统的更多详细信息,则很难回答。你最好的选择是试一试并衡量。但是对于非内存映射的情况,我建议在文件上禁用缓冲setvbuf(3)以避免读取任何额外数据(或者使用open(2) / {{3的原始Unix文件API }} / lseek(2) / read(2))。您还可以使用close(2)向操作系统提供有关如何缓冲文件页面的提示 - 在您的情况下,您可能希望通过POSIX_FADV_RANDOM告诉它您将访问文件页面随机,可能禁用预读行为,这将导致不必要的I / O.

  

如果我没有50g的内存,那么对内存映射文件是否有意义?

确实如此,只要你有足够的地址空间 - 这对于32位进程根本不起作用,但在64位进程中它会没问题。操作系统将为整个文件范围分配虚拟地址空间,但由于需求分页,在您实际读取或写入任何给定页面之前,它不会向其提交任何物理内存。如果您碰巧触摸的页面数量超过了物理内存中可以容纳的数量,那么寻呼机将只会找出最近最少使用的页面。

答案 1 :(得分:0)

  

现在我正在使用带偏移的seekg来执行此操作,但它正在采取&gt;有时3秒。

发布代码。

  

在这种情况下,内存映射文件会加快读取速度吗?如果我没有50g的ram,那么记忆映射文件是否有意义?

可能不是,而且它可能不会表现得更好,可能会无比恶化,因为你会导致英雄规模的交换。

  

我还能做些什么来加快速度吗?

发布代码。