多线程从磁盘读取?

cmo*_*cmo 14 c++ io multithreading openmp

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

可以多线程上传这个吗?

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

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

Dan*_*Dan 33

对的,这是可能的.然而:

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

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

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

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

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

|         |
Run Code Online (Sandbox Code Playgroud)

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

space ----->
|        *|  t
|        *|  i
|        *|  m
|        *|  e
|        *|  |
|       / |  |
|     /   |  |
|   /     |  V
|  /      |
|*        |
|*        |
|*        |
|*        |
Run Code Online (Sandbox Code Playgroud)

虽然并行读取看起来像

|       \ |
|        *|
|       / |
|     /   |
|   /     |
|  /      |
|*        |
|  \      |
|    \    |
|     \   |
|       \ |
|        *|
|       / |
|     /   |
|   /     |
|  /      |
|*        |
|  \      |
|    \    |
|     \   |
|       \ |
|        *|
Run Code Online (Sandbox Code Playgroud)

等等

  • 基准测试 - 使用1M读取读取每个1.5GB的7个文件并从中读取sha512,从硬盘导致1个线程为100MB/s,8个线程为50MB/s.从SSD导致1个线程为150MB/s,8个线程为500MB/s. (5认同)
  • 基本上是正确的,但是您正在假设操作系统如何将文件放在磁盘上(甚至是HD本身如何在物理介质上布置扇区).此外,SSD的搜索是"免费的".IO管道将以最低组件的速度运行,网络上传很可能是网络. (2认同)

Fox*_*ter 6

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

Windows上匹配的写调用是WriteFileGather.

对于UNIX你看readvwritev可以获得做同样的事情.