【问题标题】:Accessing separate files from separate threads, is this efficient?从单独的线程访问单独的文件,这有效吗?
【发布时间】:2019-05-30 18:23:43
【问题描述】:

我有一个加载文件和处理数据的应用程序。假设我有 10...20 个文件要处理。

一些要求,让问题更清楚:

  • 文件很小,最大可能只有几 MB
  • 可能有十几个文件,也可能有一百个
  • 一个示例可能是解析 CSV 数据或 JSON,加载游戏 3d 模型

一个想法是使用一些线程池和并行处理文件。这有效率吗?我的操作系统可以处理来自多个线程的文件访问吗?

我发现了这个问题: Accessing a single file with multiple threads

但在我的应用程序中,一个线程将访问其“自己的”文件,因此不会发生任何冲突。

在我的应用程序中,我使用的是 C++/STL,但我想了解有关 Linux 和 Windows 上文件系统的一般意见。

【问题讨论】:

  • 您确定在您的特定情况下,加载需要很长时间吗?我猜它是如此之快,以至于您的普通用户甚至都没有注意到它。
  • 我在这里问了一个一般性的问题,所以在我的简单应用程序中,文件访问速度很快(特别是如果文件在系统缓存中)。但我正在考虑这里的一般机制。

标签: c++ io operating-system filesystems


【解决方案1】:

您需要进行基准测试。(在您的情况下,可能值得使用多个线程;但是在您的情况下,加载应该非常快,即使是按顺序完成,您的普通用户也会赢'不注意)

在许多情况下,当您处理最近访问过的中等大小的文件(例如,每个不到 12 兆字节,甚至每个 0.5 GB)时,这些文件实际上位于page cache 中。所以你不会访问磁盘本身,你的程序实际上是在 RAM 中工作的(然后多线程应该是有效的)。

顺便说一句,Linux 有readahead(2)posix_fadvise(2)madvise(2) 来提示内核虚拟内存子系统(即提示页面缓存)。

如果您的常见用例是访问磁盘本身(例如因为文件很大,或者因为您最近没有访问过它们,所以它们在页面缓存中),那么多线程无济于事,因为瓶颈变成了硬件磁盘。

请记住,磁盘(甚至是 SSD 磁盘)比 RAM 慢数千倍,并且它按顺序执行 IO 操作。

另外,您可能会在parsing 文件中花费一些 CPU 时间。如果这需要大量 CPU,则值得在多个独立线程中运行。

【讨论】:

  • 谢谢!我正在考虑的文件很小,可能只有几 MB。另一个例子是并行编译:编译器可以这样做并且基本上为每个文件调用一个编译器。所以应该是可以的
  • 并行编译(例如 make -j 使用 C++ 和 GCC)涉及独立进程(GCC 本身不是多线程的)并且大部分时间 C++ 源文件都在页面缓存中(例如,因为您已保存他们最近在你的编辑器中)
  • 另外,GCC 不会在 IO 上花费太多时间。用g++ -ftime-report运行它
【解决方案2】:

根据我的经验,如果数据处理繁重,您可以获得更高的性能。在这种情况下,您确实可以并行执行程序。您还需要知道您的 cpu 有多少核心。拥有比 CPU 核心更多的线程是不值得的。 如果您的处理是“轻量级的”,那么您的线程可能总是在等待磁盘完成读取,而性能几乎没有提升。

【讨论】:

  • 是的,所以线程池、系统线程池通常分配与核心数匹配的工作线程(加上减去额外线程)。所以我有 6 个内核和 100 个文件,我仍然可以一次处理最多 6 个文件。不是 100。
猜你喜欢
  • 1970-01-01
  • 2011-12-14
  • 2011-01-27
  • 2016-08-24
  • 2017-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多