使用mmap时性能下降

时间:2013-10-14 10:40:56

标签: c++ linux performance mmap

我必须计算一个巨大的nxn矩阵(n> 100000)并以某种方式将其存储在内存中以供进一步使用。单个元素的计算是非常昂贵的(几千个触发器和内存访问),所以我无法动态计算它。但是我只需要计算一次,以后不需要修改它。我也不能假设我在系统上有足够的交换空间。这就是为什么我决定创建一个缓存文件并使用mmap将其映射到内存:

int createCacheFile(std::size_t filesize, std::string const& filename){
    //create empty file
    int fileDescriptor = open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600);
    //stretch to desired size
    lseek(fileDescriptor, filesize-1, SEEK_SET);
    return fileDescriptor;
}

//...
std::size_t n = 100000;
std::size_t fileSize = n*n*sizeof(float);
int fileDescriptor = createCacheFile(filesize,"matrix.cache");
float* memory = (float*) mmap(0, filesize, PROT_READ | PROT_WRITE, MAP_SHARED, fileDescriptor, 0);

//and now fill it...

我想比较性能并尝试了一个小的n = 10000,并将malloc,mmap与MAP_ANONYMOUS和上面的实现进行了比较。为此,矩阵完全适合RAM。虽然malloc和MAP_ANONYMOUS给出了非常相似的结果,但是当我的矩阵由文件支持时,我会得到大约10倍的惩罚。似乎内核定期停止程序,以便它可以将内容安全地写入文件。我尝试使用msync和mprotect来解决这个问题,我已经计算了矩阵的部分,以便内核提示它可以编写部分而不必停止程序但没有任何帮助。

有没有办法解决这个问题?

1 个答案:

答案 0 :(得分:0)

您还可以使用madvise(2)系统调用通知内核不太有用的页面(可能包含MADV_SEQUENTIALMADV_DONTNEED ...)。也许posix_fadvise(2)系统调用可能对文件段有帮助。最终readahead(2)(在另一个线程中,因为它阻塞)也可能有所帮助。

该文件可能位于快速文件系统中,可能是tmpfs个....

也许更换快速磁盘(SSD)可能也很有用。 swapon(2)系统调用(和swapon命令)。