gpt4 book ai didi

c++ - 过多的线程数会在文件读取时产生更好的结果

转载 作者:行者123 更新时间:2023-12-05 02:35:53 25 4
gpt4 key购买 nike

我有一亿个文件,我的程序在每次启动时都会读取所有这些文件。我一直在寻找使这个过程更快的方法。在路上,我遇到了一些奇怪的事情。我的 CPU 有 4 个物理内核,但使用更高的线程数读取这么多文件会产生更好的结果。这很有趣,因为打开的线程多于 CPU 的逻辑核心数应该有点毫无意义。

8     Threads: 29.858 s
16 Threads: 15.882 s
32 Threads: 9.989 s
64 Threads: 7.965 s
128 Threads: 8.275 s
256 Threads: 8.159 s
512 Threads: 8.098 s
1024 Threads: 8.253 s
4096 Threads: 8.744 s
16001 Threads: 10.033 s

为什么会出现这种情况?是磁盘瓶颈吗?

  • 做了功课,剖析了代码,实际上 %95 的运行时间由 read()open()close()
  • 我正在读取每个文件的前 4096 个字节(我的页面大小)
  • Ubuntu 18.04
  • 英特尔 i7 6700HQ
  • 三星 970 Evo Plus NVMe SSD
  • 海湾合作委员会/G++ 11

最佳答案

Why this may occur ?

如果您在“/a/b/c/d/e”打开一个文件,然后从文件中读取一个数据 block ;操作系统可能必须获取“/a”的目录信息,然后获取“/a/b”的目录信息,然后获取“/”的目录信息a/b/c", 那么... 它可能加起来总共从磁盘中获取 6 个 block (5 个目录信息 block ,然后是一个文件数据 block ),并且这些 block 可能分散在各处磁盘。

如果打开一亿个文件,从每个文件中读取一 block 文件数据;那么这可能涉及到获取 6 亿个东西(5 亿条目录信息和 1 亿条文件数据)。

做这 6 亿件事情的最佳顺序是什么?

通常会涉及到目录信息缓存和文件数据缓存(并且所有可以由已经缓存的数据满足的请求都应该尽快完成,然后才将数据从缓存中逐出以为其他数据腾出空间)。通常磁盘硬件也有规则(例如在切换到下一个“磁盘 block 组”之前更快地访问同一“磁盘 block 组”中的所有 block )。有时磁盘硬件存在并行性(例如,来自同一区域的两个请求不能并行完成,但来自不同区域的 2 个请求可以并行完成)。

执行这 6 亿件事情的最佳顺序是操作系统可以计算出来的。

更具体地说;做这 6 亿件事的最佳顺序是操作系统可以计算出来的; 当且仅当操作系统实际上知道所有这些

如果您有(例如)8 个线程发送一个请求(例如打开一个文件)然后阻塞(不使用 CPU 时间)直到挂起的请求完成;那么操作系统一次最多只能知道 8 个请求。换句话说;操作系统优化文件 IO 请求执行顺序的能力受到待处理请求数量的限制,而待处理请求数量又受到您拥有的线程数量的限制。

理想情况下;单个线程将能够要求操作系统“打开这个一亿个文件列表中的所有文件”,以便操作系统可以完全优化顺序(线程管理开销最少)。可悲的是,大多数操作系统不支持这样的东西(例如 POSIX 异步 IO 不支持任何类型的“异步打开”)。

拥有大量线程(它们在等待文件系统和/或磁盘驱动程序实际完成请求时全部被阻塞并且不使用任何 CPU 时间)是提高操作系统性能的唯一方法能够优化 IO 请求的顺序。

关于c++ - 过多的线程数会在文件读取时产生更好的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70430716/

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