如果并行执行,磁盘文件操作是否更快
Are disk file operations faster if executed in parallel?
考虑有N个文件要完全写入磁盘(即从所有文件缓冲区中刷新)。对于每个文件,我们使用WriteFile
写入少量(相对于HDD寻道时间)数据,例如64KB,然后在该文件上调用FlushFileBuffers
以确保该文件的数据完全刷新到硬盘驱动器。
如果我们按顺序逐个写入&flush文件,那么我预计大约需要N*seekTime
+ N*writeTime
时间,其中seekTime
是将硬盘磁头定位到适当扇区的时间(可能需要整个磁盘旋转的时间),writeTime
是磁盘按顺序写入64KB数据所需的时间。使用这种一个接一个的方法,我们没有给操作系统任何优化的空间,因为我们定义了必须刷新文件的顺序。
在操作系统的一些支持下,可以通过重新安排文件写和刷新的顺序来实现性能改进,以便考虑到磁盘旋转(即磁头在磁盘上的当前位置),重新安排文件操作,以便从几乎不需要旋转的文件开始(即最接近磁盘磁头当前位置的文件),并以几乎需要完全旋转的磁盘结束。
问题是:操作系统(特别是Windows)提供这样的优化吗?换句话说,是否可以通过在N个线程中并行运行文件写和刷新操作(每个文件一个线程)来提高性能?或者它会导致额外的重新定位操作,从而降低性能(作为硬盘驱动器的一种上下文切换)?
你应该首先问自己,并在这里解释,为什么你需要冲水。你想要达到的不一定是实际发生的。
如果您确实想优化应用程序,使其在物理设备上产生特定的访问模式,那么您的解决方案将非常依赖于硬件。在测试用例中看起来像是优化的东西,在另一个场景中可能会达到相反的效果。例如,文件碎片怎么办?那raid盘呢?那么网络文件系统呢?那么SSD驱动器呢?运行在同一台机器上的其他进程对同一磁盘的并发访问怎么办?
使磁盘访问快速的关键是缓冲。如果你不是绝对需要打败它,就不要打败它。
您需要进行基准测试,因为它是特定于操作系统、文件系统和硬件的。在我的Linux系统上,许多文件操作都要通过页面缓存,所以如果两个程序(或同一个程序运行两次)几乎同时访问一个文件,那么最近的访问可能不涉及任何物理磁盘I/O。Linux和POSIX甚至有一些系统调用来帮助页面缓存(posix_fadvise(2), madvise(2), readahead(2)…)
我不了解Windows,但听说并相信在这种缓存上它比Linux效率低的谣言。
硬件限制通常是一个非常重要的瓶颈。把你的磁盘换成固态硬盘可能是值得的。
a aik, old BSD &SunOS,Linux磁盘驱动程序做了您建议的优化(重组I/O操作以降低seek &旋转延迟)。今天,这并不重要(磁盘控制器本身会将"逻辑"扇区映射到"物理"扇区)。
我相信Windows没有IO调度,事实上它甚至把大的IOs分成256KB的小块。Linux内置IO调度。
也就是说,一些驱动程序和磁盘会重新排序。通常,IO/sec速率增加到更高的队列深度。晶盘基准测试采用QD32模式。
ssd 当然做到了这一点,这很容易从具有高队列深度的基准测试中看出。ssd还具有硬件并行性。当你增加随机读取的队列深度时,它们会变得更快。
我在Windows上的桌面磁盘上发现,顺序的小write-through IOs的速度比磁盘查找速度快得多。要么控制器是写缓存,要么磁盘几何结构确实适合顺序写,即使没有缓存。
- 某些 boost::asio 异步函数是否将处理程序连接到操作,以便处理程序被触发一次?
- 标记为 std::memory_order_seq_cst 的单个原子操作是否会在所有位置触发顺序一致性?
- 如何检测函数是否执行IO操作
- 当其他线程正在编写线程安全时,我是否必须互斥读操作
- 如果 RMW 操作没有任何变化,是否可以针对所有内存顺序对其进行优化
- 是否有一个C++函数可以准确返回平方根反比的内置 CPU 操作 RSQRTSS 的值?
- 负载是否可以在获取操作下方滑动/存储是否可以漂浮在C++释放上方?
- 如何使客户端在将数据写入 C++ 管道之前检查服务器是否完成了从管道的读取操作
- 我是否缺少<实验/文件系统>移动操作?
- 是否可以访问类数据成员并在析构函数中对它们执行操作?
- 是新的(&*p)双倍;一个无操作。因此,uninitialized_default_construct是否也变得无操作?
- blaze-lib 的元素操作是否自动并行?
- 是否有可能具有放入容器的移动操作的类型?
- 是否可以拦截/检测关闭 PC 并首先执行操作的请求?
- 在链接的程序集文件中,我想从 c++ 调用代码访问变量.是否可以在不触发访问冲突的情况下执行此操作?
- 编译器是否会简化按顺序执行多次的操作
- 在C++中,当表达式涉及对象时,将表达式赋值到对象中时,是否有定义的操作顺序?
- 静态断言添加操作是否可用
- 我是否应该避免在循环中的常数之间进行操作
- 我们是否可以使用 SEAL / PySEAL 库对加密数据执行除法操作Microsoft?