【问题标题】:why multi-thread cant improve a mmap task?为什么多线程不能改进 mmap 任务?
【发布时间】:2021-06-13 09:10:50
【问题描述】:

我有一个大任务,需要读取 500 个文件(共 50G)。

对于每个文件,我都应该将其读出,并根据文件中的数据进行一些计算。只是计算,没有别的。而且我可以确保任务是独立的,只需共享一些要读取的符号对象(我认为这不会是问题)。

目前,我使用mmap获取文件内容的起始指针,并循环计算。

在单线程中,我运行任务,花费 30 秒,

我在线程池中运行它,花了我 35 秒(6 个线程)。

我的机器是16G内存,2.2G hz cpu,8线程。

我尝试了很多设置,并仔细确保任务的独立性。

我不太擅长硬件,IO 有没有硬性限制,限制了我的速度?谁能提醒我有什么可以读的吗?

对不起,代码太复杂了,我这里做不了有效的演示。

【问题讨论】:

  • 您是受 IO 限制还是受 CPU 限制?如果只是 IO,线程将无济于事。事实上,这可能会使事情变得更糟,因为您现在有 N 个线程竞争相同的 IO 资源。如果您的驱动器速度很慢,而您的 CPU 速度很快,那么单线程可能是最有效的。如果您的驱动器速度太快,CPU 无法跟上一个线程,请考虑使用线程,但请注意,您的计算机的驱动器可能比普通驱动器快得多。
  • 这就是性能监控工具,甚至是您的操作系统附带的内置工具,都可以提供帮助的地方。看看你的驱动器的峰值速度是多少。
  • @tadman 我通过 iptop 检查,但似乎没有磁盘写入/读取任务。我认为它们已被缓存到 mem 中,这很奇怪,因为没有 io 绑定,它应该加快速度
  • 您需要了解有关驱动器限制的更多信息。 SATA 并不总是最好的。 NVMe 可以很壮观。
  • 因为磁盘不是多线程的。

标签: c++ multithreading io mmap


【解决方案1】:

如果您想加载整个文件或使用 madvise,可以尝试使用 mmap 上的 MAP_POPULATE 标志进行预读。

这里没有提到最重要的硬件细节,如果你从 SSD 或 HDD 读取,但我假设你使用 SSD,否则线程池代码会慢得多。

我不明白你为什么在这里使用映射。 mmap 文件只有三个正当理由,首先,磁盘上的数据结构很复杂,而且您喜欢四处寻找,这很慢,因为它使预读效率大大降低。您需要在进程之间共享内存。或者,当您的系统面临内存压力时,您处理大型文件并需要操作系统功能将数据交换到文件中(所有数据库都只是出于这个原因)。

【讨论】:

  • 我可以使用 mmap 或打开,只是我更喜欢使用 mmap 来读取文件。我是 SSD。
  • 可以,但是 mmap 不是针对磁盘 io 优化的 API。
  • @Lothar mmap 不是针对磁盘 io 优化的 API 确实如此。 mmap() 的问题是你必须付出巨大的代价来为你想要阅读的每一页创建虚拟内存映射。如果您要多次访问数据,那没关系。但如果你只打算读取一次数据,那通常是不值得付出的代价。 read()/pread()O_DIRECT 可能会更快读取一次。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-22
  • 1970-01-01
  • 1970-01-01
  • 2011-03-03
  • 2019-03-02
  • 2016-06-10
相关资源
最近更新 更多