Linux C++ 从 5GB 和 64MB 文件中读取 64 字节的 Pread 函数的性能比较

Performance Comparison of Linux C++ pread Function for Reading 64 Bytes from 5GB and 64MB Files

提问人:Oliver 提问时间:10/31/2023 更新时间:10/31/2023 访问量:83

问:

我正在做一个涉及从文件中读取数据的C++项目,我想优化读取过程。具体来说,我正在使用 pread 函数读取 64 字节的数据。我有两种情况:

  • 从 5GB 文件中读取 64 字节。
  • 从 64MB 文件中读取 64 字节。

我的目标是确定哪种方案会导致更快的数据检索,或者它们是否达到相同的速度。

硬件/软件环境:

  • Intel(R) Core i7-11700K CPU(16 个逻辑内核,3.60GHz,640KB L1 缓存,4.0MB L2 缓存和 16.0MB LLC)
  • 32GB DDR4 内存
  • 1TB 三星 NVMe 固态硬盘
  • Ubuntu 20.04.6 LTS的
  • 海湾合作委员会 9.4.0
  • 文件系统:ext4

下面是我用于这两种方案的基本代码结构:

#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <chrono>
using namespace std;
using namespace chrono;

int main() {
    const char* filename = "file_XX_MB";  // XX may be 5GB or 64MB
    int fd = open(filename, O_RDONLY);
    off_t offset = 2000000000;
    char buffer[64];
    auto st = high_resolution_clock::now();
    ssize_t bytesRead = pread(fd, buffer, sizeof(buffer), offset);
    auto en = high_resolution_clock::now();
    cout << "pread time: " << duration_cast<nanoseconds>(en - st).count() << endl;
    close(fd);
    return 0;
}

我已经测试了该程序 10 次并计算了平均读取延迟。(见下文)

  • 从 5GB 文件中读取 64 字节:1758.6 ns
  • 从 64MB 文件中读取 64 字节:1266.9 ns

由于SSD的高效随机读取性能,我认为这两种场景的延迟应该是一样的。但是,测试结果表明,从小文件读取比从大文件读取更快。文件大小似乎是一个重要因素,这让我感到困惑。pread

任何见解、性能比较或解释将不胜感激!

C++ Linux IO 操作系统 文件系统

评论

0赞 Alan Birtles 10/31/2023
半微秒的差异并不大,可能有很多因素导致了差异(如果有的话)。操作系统将缓存数据,ssd 可能也在做同样的事情
0赞 Pepijn Kramer 10/31/2023
为了快速访问这么大的文件,不要使用普通文件,而是使用内存映射文件 (mmap),特别是如果您需要随机访问。旁注:文件名应为std:;string(或 std::string_view),不要使用 std::chrono::high_resolution_clock,而是使用 std::chrono::steady_clock 并停止使用using namespace
1赞 Homer512 11/1/2023
您假设在文件中定位块需要恒定的时间,但我不明白为什么会这样。毕竟,文件系统必须处理碎片化。例如,如果您使用的是 ext4 文件系统,则元数据位于扩展数据块树中。可以合理地假设较大的文件具有较大的树,并且搜索时间稍长。这假设您正在访问磁盘,而不仅仅是页面缓存
1赞 Homer512 11/1/2023
我不知道您的用例,但对我来说,更公平的比较是在一个 5 GiB 文件和 320 x 16 MiB 文件中查找多个随机偏移量的数据。我怀疑那么一个大文件会很容易获胜
0赞 Oliver 11/1/2023
@PepijnKramer是的,在大文件中似乎是更好的选择。我需要重新考虑 IO 设计。感谢您的旁注:Dmmap

答: 暂无答案