如何使用c++在Windows上提高读取数据的速度
How to increase speed of reading data on Windows using c++
我正在使用CreateFile/ReadFile
和缓冲大小为4096字节从卷快照读取数据块。我面临的问题是ReadFile
太慢了,我能够在45秒内读取68439块即267 Mb,我如何提高速度?下面是我使用的一部分代码,
block_handle = CreateFile(block_file,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL);
if(block_handle != INVALID_HANDLE_VALUE)
{
DWORD pos = -1;
for(ULONG i = 0; i < 68439; i++)
{
sectorno = (i*8);
distance = sectorno * sectorsize;
phyoff.QuadPart = distance;
if(pos != phyoff.u.LowPart)
{
pos=SetFilePointer(block_handle, phyoff.u.LowPart,&phyoff.u.HighPart,FILE_BEGIN);
if (phyoff.u.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
{
printf("SetFilePointer Error: %dn", GetLastError());
phyoff.QuadPart = -1;
return;
}
}
ret = ReadFile(block_handle, data, 4096, &dwRead, 0);
if(ret == FALSE)
{
printf("Error Read");
return;
}
pos += 4096;
}
}
我应该使用OVERLAPPED
结构吗?或者可能的解是什么?注意:代码不是线程的
等待正面响应
我不太明白你为什么要用这些极其低级的系统功能。
就我个人而言,我使用C风格的文件操作(使用fopen和read)以及c++风格的操作(使用fstream和read,参见此链接)来读取原始二进制文件。从本地磁盘读取的速度大约为100MB/秒。在你的情况下,如果你不想使用标准的C或c++文件操作,我的猜测是你的代码变慢的原因是由于你在每个块之后执行一个seek。你真的需要为每个块调用SetFilePointer吗?如果这些块是连续的,则不需要这样做。
另外,尝试不同的块大小,不要害怕超过1MB。
您的问题是碎片化的数据读取。您不能通过修改ReadFile参数来解决这个问题。你需要整理你的阅读。这里有三种方法:
-
整理磁盘上的数据
-
整理读的碎片。也就是说,收集所有需要的读取,但还不读取任何内容。将读取的数据按顺序排序。按顺序读取所有内容,尽可能跳过SetFilePointer(即顺序块)。这将大大加快总读取速度,但在第一次读取开始之前会引入延迟。
-
内存映射数据。将所有数据复制到内存中,并从内存中随机读取数据。这是否可能取决于总共有多少数据。
另外,您可能想要更花哨一些,并尝试使用缓存。当您读取一个数据块时,虽然下一次读取不是连续的,但它很可能很接近。因此,当读取一个块时,顺序地将附近的大量数据块读入内存。在下一次读取之前,检查新的读取是否已经在内存中-从而节省查找和磁盘访问。测试、调试和调优需要大量的工作,所以我不建议这样做,除非这是一个关键任务的优化。还要注意,您的操作系统和/或磁盘硬件可能已经在做这些事情了,所以准备好看不到任何改进。
- 如果可能的话,顺序读取(并告诉CreateFile您打算使用
FILE_FLAG_SEQUENTIAL_SCAN
顺序读取)。 - 避免不必要的查找。如果你是按顺序阅读,你不应该需要任何搜索。
- 读取较大的块(如典型簇大小的整数倍)。我相信Windows自己的文件拷贝使用的读取量是8mb而不是4kb。考虑使用系统分配粒度的整数倍(可从GetSystemInfo获得)。
- 从对齐的偏移量中读取(你似乎正在这样做)。 读取到与页面对齐的缓冲区。考虑使用VirtualAlloc来分配缓冲区。
- 请注意,文件碎片可能会导致昂贵的查找。你对此无能为力。
- 请注意,卷压缩可以使查找特别昂贵,因为它可能必须从头解压缩文件以找到文件中间的起始点。
- 请注意,卷加密可能会减慢速度。你能做的不多,但要注意。
- 请注意,其他软件,如反恶意软件,可能会扫描整个文件,每次你触摸它。更少的操作将最小化这种影响。
- 如何在ros2中从rosbag2读取数据
- OpenCV 和从 OutputArrays 或 (Mat) 读取数据
- 使用C++从磁卡读卡器MT188读取数据
- HDF5 简单读取数据集失败
- 嵌套结构,从由空行分隔的文件中读取数据
- 不要从输入队列套接字读取数据
- 从文件中读取数据,操作员>>
- 如何从excel文件中读取数据并存储到变量中?
- C++:从文件中读取x y数据会产生无限循环吗
- 无法通过FT232RL读取数据
- 如何从QNetworkReply读取数据?
- C++ 逐行从文件(包含空格)读取数据
- 通过显示一行星号来创建条形图,该条形图将读取数据的输入文件
- 我们可以从 TXT 文件中读取数据并使用 C 和 C++ 将其保存到 SQL 数据库吗?
- 从多个 tcp 连接读取数据
- 从文本文件中读取数据并删除所有换行符空格,并在 C++ 控制台中显示
- Qt TCP服务器不从客户端读取数据
- 累积从 C++11 中的文件中读取数据的整数
- 从 txt 文件中读取数据的最简单方法
- 从 txt 文件中读取数据的 Getline