多线程从磁盘读取?

时间:2012-11-16 17:46:08

标签: c++ multithreading io openmp

假设我需要从磁盘上保存的同一个文件中读取许多不同的独立数据块。

是否可以对此上传进行多线程化?

相关:同一处理器上的所有线程是否使用相同的IO设备从磁盘读取?在这种情况下,多线程根本不会加速上传 - 线程只是排队等候。

(我目前正在使用OpenMP进行多线程处理。)

5 个答案:

答案 0 :(得分:29)

是的,有可能。但是:

  

同一处理器上的所有线程是否都使用相同的IO设备从磁盘读取?

是。磁盘上的读头。例如,尝试并行复制两个文件而不是串行复制。并行需要更长的时间,因为操作系统使用调度算法来确保两个线程/进程之间的IO速率“公平”或相等。因此,读头将在磁盘的不同部分之间来回跳转,从而减慢了过程。与寻找数据的时间相比,实际读取数据的时间非常短,当您同时读取磁盘的两个不同部分时,您大部分时间都在寻找数据。

请注意,所有这些都假定您使用的是硬盘。 如果您正在使用SSD,它并不会慢,但它也不会更快。编辑:根据评论,并行实际上对SSD来说更快。使用RAID时,情况变得更加复杂,(显然)取决于您使用的RAID类型。

这就是它的样子(我已经将圆形磁盘展开成矩形,因为ascii圆圈很难,并且简化了数据布局以便于阅读):

假设文件被盘片上的某个空格分开,如下所示:

|         |

系列阅读看起来像(*表示阅读)

space ----->
|        *|  t
|        *|  i
|        *|  m
|        *|  e
|        *|  |
|       / |  |
|     /   |  |
|   /     |  V
|  /      |
|*        |
|*        |
|*        |
|*        |

虽然并行读取看起来像

|       \ |
|        *|
|       / |
|     /   |
|   /     |
|  /      |
|*        |
|  \      |
|    \    |
|     \   |
|       \ |
|        *|
|       / |
|     /   |
|   /     |
|  /      |
|*        |
|  \      |
|    \    |
|     \   |
|       \ |
|        *|

答案 1 :(得分:5)

如果您在Windows上执行此操作,则可能需要查看ReadFileScatter功能。它允许您在单个异步调用中从文件中读取多个段。这将允许操作系统更好地控制文件IO瓶颈,并希望优化读取。

Windows上匹配的写入调用将是WriteFileGather

对于UNIX,您正在查看readvwritev来执行相同操作。

答案 2 :(得分:2)

如其他答案所述,并行读取可能会更慢,具体取决于文件在磁盘上的物理存储方式。因此,如果头部必须移动很长的距离,则可能导致实际的减速。据说存在可以有效支持多个同时读写的存储系统。我能想象的最简单的是SSD磁盘。我自己使用IBM的宏伟存储系统,可以同时执行读取和写入而不会减速。 因此,我们假设您拥有这样一个文件系统和物理存储,它不会减慢并行读取速度。

在这种情况下,并行读取非常合乎逻辑。一般来说,有两种方法可以实现这一目标:

  1. 如果您想使用标准C / C ++库来执行IO,那么您唯一的选择是为每个线程保留一个打开的文件句柄(描述符)。这是因为文件指针(指向文件中的读取或写入位置)保留在每个句柄中。因此,如果您尝试从同一个文件句柄同时阅读,您将无法知道您实际阅读的内容。
  2. 使用特定于平台的API来执行异步(OVERLAPPED)IO。在Windows上,您使用WinAPI函数和所谓的OVERLAPPED IO。在Unix / Linux上你有posix AIO,虽然我知道它的使用是不鼓励的,虽然我没有看到任何令人满意的解释,为什么会这样。
  3. 我自己在linux和windows上实现了两种fd / thread方法,在windows上实现了OVERLAPPED方法。两者都很有效。

答案 3 :(得分:0)

您将无法加快读取到磁盘的过程。如果您在编写的同时进行计算,并行化将有所帮助。但纯粹的写作将受到处理器和硬盘驱动器之间通道带宽的限制,更值得注意的是,硬盘驱动器本身(我的硬盘驱动器的速度为30MB / s,我听说raid设置为120MB / s)网络,但不要依赖它。)

答案 4 :(得分:0)

如果您使用标准系统功能,那么通过操作系统的设计,磁盘的多次读取应该是线程安全的,不需要手动锁定它,只打开文件只读。 (否则您将收到文件访问错误。)

顺便说一下,在实践中你没有必要从磁盘读取,操作系统将决定它将从何处为你提供服务。它通常预取读取并从内存中提供服务。