c – 连续调用mmap,任何缓存?

我在矢量中读到:

int readBytes(string filename, vector<uint32_t> &v)
{
    // fstat file, get filesize, etc.

    uint32_t *filebuf = (uint32_t*)mmap(0,filesize,PROT_READ,
                                        MAP_FILE|MAP_PRIVATE,
                                        fhand,0);
    v = std::vector<uint32_t>(filebuf,filebuf+numrecords);
    munmap(filebuf, filesize);
}

在main()中,我有两个连续的调用(纯粹作为测试):

vector<uint32_t> v(10000);    
readBytes(filename, v);
readBytes(filename, v);
// ...

第二次调用几乎总是提供更快的时钟时间:

Profile time [1st call]: 0.000214141 sec
Profile time [2nd call]: 0.000094109 sec

查看系统调用表明内存块是不同的:

mmap(NULL, 40000, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fe843ac8000
mmap(NULL, 40000, PROT_READ, MAP_PRIVATE, 4, 0) = 0x7fe843ac7000

为什么第二次通话更快?巧合?什么,如果有的话,缓存?

解决方法:

假设你在谈论* NIX-ish,可能还有一个页面缓存,它的工作就是缓存这种数据以获得这种加速.除非在从缓存中逐出这些页面的调用之间出现其他问题,否则它们仍将存在.

因此,第一次调用可能需要:

>分配页面
>将页面映射到您的进程地址空间
>将这些页面中的数据复制到您的向量中(可能会导致数据从磁盘中出错)

第二个调用可能会发现页面仍然在缓存中,并且只需要:

>将页面映射到您的进程地址空间
>将这些页面中的数据复制到您的向量中(这次它们已预先出现故障,因此这是一个简单的内存操作)

事实上,我已经跳过了一个步骤:评论中的open / fstat步骤可能也会通过inode缓存加速.

上一篇:linux – mmap的大小限制是多少


下一篇:mmap(内存映射)