gpt4 book ai didi

c++ - Linux 和 Windows : Using Large Files to save physical memory

转载 作者:可可西里 更新时间:2023-11-01 11:03:07 26 4
gpt4 key购买 nike

下午好,我们已经实现了一个C++的cKeyArray类来测试我们是否可以使用Large File API来节省物理内存。在 Centos Linux 测试期间,我们发现 Linux 文件 API 与使用堆进行随机访问处理一样快。以下是数字:对于一个 2,700,000 行的 SQL 数据库,其中每行的 KeySize 为 62 字节,

使用 LINUX 文件 API 的 cKeyArray 类BruteForceComparisons = 197275 BruteForceTimeElapsed = 1,763,504,445 微秒每个 BruteForce Comparisons 需要两次随机访问,每次随机访问所需的平均时间 = 1,763,504,445 微秒/(2 * 197275) = 4470 微秒

堆,没有 cKeyArray 类

BruteForceComparisons = 197275 BruteForceTimeElapsed = 1,708,442,690 微秒每次随机访问所需的平均时间 = 4300 微秒。

在 32 位 Windows 上,数字是,

使用 Windows 文件 API 的 cKeyArray 类BruteForceComparisons = 197275 BruteForceTimeElapsed = 9243787 毫秒每次随机访问的平均时间为 23.4 毫秒

堆,没有cKeyArray类BruteForceComparisons = 197275 BruteForceTimeElapsed = 2,141,941 毫秒每次随机访问所需的平均时间为 5.4 毫秒

我们想知道为什么 Linux cKeyArray 数字与 Linux 堆数字一样好,而在 32 位 Windows 上平均堆随机访问时间是 cKeyArray Windows 文件 API 的 4 倍。有什么方法可以加快 Windows cKeyArray 文件 API 的速度吗?

之前,我们从 Stack Overflow 收到了很多关于使用 Windows 内存映射文件 API 的好建议。基于这些 Stack Overflow 建议,我们实现了一个内存映射文件 MRU 缓存类,它可以正常运行。

因为我们想开发一个跨平台的解决方案,所以我们想尽职调查看看为什么 Linux 文件 API 这么快?谢谢你。我们正在尝试在下面发布 cKeyArray 类实现的一部分。

#define KEYARRAY_THRESHOLD 100000000   
// Use file instead of memory if requirement is above this number


cKeyArray::cKeyArray(long RecCount_,int KeySize_,int MatchCodeSize_, char* TmpFileName_) {
RecCount=RecCount_;
KeySize=KeySize_;
MatchCodeSize=MatchCodeSize_;
MemBuffer=0;
KeyBuffer=0;
MemFile=0;
MemFileName[0]='\x0';
ReturnBuffer=new char[MatchCodeSize + 1];
if (RecCount*KeySize<=KEYARRAY_THRESHOLD) {
InMemory=true;
MemBuffer=new char[RecCount*KeySize];
memset(MemBuffer,0,RecCount*KeySize);
} else {
InMemory=false;
strcpy(MemFileName,TmpFileName_);
try {
MemFile=
new cFile(MemFileName,cFile::CreateAlways,cFile::ReadWrite);
}
catch (cException e)
{
throw e;
}
try {
MemFile->SetFilePointer(
(int64_t)(RecCount*KeySize),cFile::FileBegin);
}
catch (cException e)
{
throw e;
}
if (!(MemFile->SetEndOfFile()))
throw cException(ERR_FILEOPEN,MemFileName);

KeyBuffer=new char[KeySize];
}
}

char *cKeyArray::GetKey(long Record_) {
memset(ReturnBuffer,0,MatchCodeSize + 1);
if (InMemory) {
memcpy(ReturnBuffer,MemBuffer+Record_*KeySize,MatchCodeSize);
} else {
MemFile->SetFilePointer((int64_t)(Record_*KeySize),cFile::FileBegin);
MemFile->ReadFile(KeyBuffer,KeySize);
memcpy(ReturnBuffer,KeyBuffer,MatchCodeSize);
}
return ReturnBuffer;
}


uint32_t cKeyArray::GetDupeGroup(long Record_) {
uint32_t DupeGroup(0);
if (InMemory) {
memcpy((char*)&DupeGroup,
MemBuffer+Record_*KeySize + MatchCodeSize,sizeof(uint32_t));
} else {
MemFile->SetFilePointer(
(int64_t)(Record_*KeySize + MatchCodeSize) ,cFile::FileBegin);
MemFile->ReadFile((char*)&DupeGroup,sizeof(uint32_t));
}
return DupeGroup;
}

最佳答案

在 Linux 上,操作系统积极地将文件数据缓存在主内存中——因此,尽管您没有为文件内容显式分配内存,但它们仍然存储在 RAM 中。这是一个不错的链接,其中包含有关 page cache 的更多信息-- 该描述中只遗漏了一件事,即大多数 Linux 文件系统实际上将标准 I/O 接口(interface)实现为页面缓存周围的薄包装器。这意味着即使您没有显式地对文件进行内存映射,系统仍将其视为在幕后进行了内存映射。这就是为什么您会看到两种方法的性能大致相同。

我支持将特定于平台的内容分解出来的建议,并使用对每个平台来说最快的方法。一定要进行基准测试——永远不要对性能做出假设。

关于c++ - Linux 和 Windows : Using Large Files to save physical memory,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5251483/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com