在尝试使用内存映射文件创建多 GB 文件(大约 13 GB)时,我遇到了 mmap() 的问题。最初的实现是在 Windows 上使用 boost::iostreams::mapped_file_sink 在 c++ 中完成的,一切顺利。然后代码在 Linux 上运行,在 Windows 上花费几分钟的时间在 Linux 上则变成了几个小时。
这两台机器是相同硬件的克隆:Dell R510 2.4GHz 8M 高速缓存 16GB RAM 1TB 磁盘 PERC H200 控制器。
Linux 是 Oracle Enterprise Linux 6.5,使用 3.8 内核和 g++ 4.83。
有人担心 boost 库可能存在问题,因此使用 boost::interprocess::file_mapping 和本机 mmap() 完成了实现。所有三个人都表现出相同的行为。当 Linux 性能严重下降时,Windows 和 Linux 性能在一定程度上相当。
完整的源代码和性能数据链接如下。
// C++ code using boost::iostreams
void IostreamsMapping(size_t rowCount)
{
std::string outputFileName = "IoStreamsMapping.out";
boost::iostreams::mapped_file_params params(outputFileName);
params.new_file_size = static_cast<boost::iostreams::stream_offset>(sizeof(uint64_t) * rowCount);
boost::iostreams::mapped_file_sink fileSink(params); // NOTE: using this form of the constructor will take care of creating and sizing the file.
uint64_t* dest = reinterpret_cast<uint64_t*>(fileSink.data());
DoMapping(dest, rowCount);
}
void DoMapping(uint64_t* dest, size_t rowCount)
{
inputStream->seekg(0, std::ios::beg);
uint32_t index, value;
for (size_t i = 0; i<rowCount; ++i)
{
inputStream->read(reinterpret_cast<char*>(&index), static_cast<std::streamsize>(sizeof(uint32_t)));
inputStream->read(reinterpret_cast<char*>(&value), static_cast<std::streamsize>(sizeof(uint32_t)));
dest[index] = value;
}
}
最后一个测试是用 Python 完成的,以便用另一种语言重现这一点。掉落发生在同一个地方,所以看起来是同样的问题。
# Python code using numpy
import numpy as np
fpr = np.memmap(inputFile, dtype='uint32', mode='r', shape=(count*2))
out = np.memmap(outputFile, dtype='uint64', mode='w+', shape=(count))
print("writing output")
out[fpr[::2]]=fpr[::2]
对于 C++ 测试,Windows 和 Linux 具有相似的性能,最多可达 3 亿个 int64(Linux 看起来稍快一些)。对于 C++ 和 Python,Linux 上的性能似乎下降了大约 3Gb(每个 int64 4 亿 * 8 字节 = 3.2Gb)。
我知道在 32 位 Linux 上 3Gb 是一个神奇的边界,但我不知道 64 位 Linux 上有类似的行为。
结果的要点是,在 4 亿个 int64 下,Windows 上的时间为 1.4 分钟,Linux 上的时间为 1.7 小时。我实际上正在尝试映射近 13 亿个 int64。
谁能解释一下为什么 Windows 和 Linux 之间的性能差距如此之大?
任何帮助或建议将不胜感激!
负载测试.cpp http://pastie.org/9645329
Makefile http://pastie.org/9645338
负载测试.vcxproj http://pastie.org/9645344
更新了 mmap_test.py http://pastie.org/9649752
原始mmap_test.py http://pastie.org/9645348
更新结果 http://goo.gl/Xqhngt更新了 Python 代码...Python 速度现在可与 C++ 相媲美
原始结果 http://goo.gl/n8QMff注意:Python 结果已过时