我正在开发一个应用程序,它收集包含硬盘驱动器所有文件的列表 之后它会将文件写入硬盘。
我想问一下:执行此任务的最佳并发线程数是多少?
我的意思是我应该有多少线程在不制作硬盘的情况下读取硬盘 因为很多线程同时读取它而变慢。
谢谢!
答案 0 :(得分:5)
起初,我说一个!
这实际上取决于要读取的数据是否需要复杂的计算才能进行详细说明。在这种情况下,可以方便地实例化多个线程来详细说明不同的磁盘数据;但只有在同一系统上有多个CPU时才这很方便。
否则,多个线程会使HDD比必要的压力更大:来自不同线程的并发读取将发出 seek 操作来读取文件块(*),从而引入可能减慢速度的开销系统,取决于读取的文件数和文件大小。
按顺序读取文件。
(*)操作系统确实尝试按顺序存储相同的文件块,以加快读取操作。磁盘碎片发生,因此非顺序碎片需要搜索操作,这需要更多时间来尊重同一位置的读取操作。尝试并行读取多个文件,会导致一堆搜索,因为单个文件块是连续的,而多个文件块可能不连续。
答案 1 :(得分:3)
一个帖子。如果您正在同时阅读和写入并且您的目标是与您的源不同的磁盘,那么2个线程。我要补充说,如果你正在对文件进行其他操作(例如解压缩),解压缩部分可以在第三个线程上完成。
举一些例子(我忽略了连接点,重新分析点......)
我正在设想磁盘可以一次执行一个操作,并且每次“多任务”在不同的读/写之间切换时,它的速度会丢失。机械磁盘有这个问题(但技术上NCQ可能有帮助)。固态硬盘我不知道(但我知道如果你一次尝试做2次操作,USB棒很慢)
我已经搜索了你是如何做到的......我还没有找到任何“具体”的例子,但我有一些指向Windows API的链接,你可以从这里开始:
显示卷路径: http://msdn.microsoft.com/en-us/library/cc542456%28VS.85%29.aspx
GetVolumePathName:http://msdn.microsoft.com/en-us/library/aa364996(v=VS.85).aspx
GetVolumeInformationByHandleW http://msdn.microsoft.com/en-us/library/aa964920(v=VS.85).aspx
答案 2 :(得分:3)
永远不要同时处理IO密集操作。由于磁盘探测在不同线程/文件之间切换时浪费了大量时间,因此速度较慢。
如果我在IO操作中有几个线程,我该怎么办?同时生成操作,并执行单线程操作。我们有一个容器,比如ConcurrentQueue<T>
(或者你自己编写的线程安全队列),并且有10个线程,将从这些文件中读取1.txt 2.txt ... 10.txt。你把“读取请求”同时放在队列中,另一个线程处理所有请求(打开1.txt,得到你想要的,继续2.txt),磁盘探测器不会忙于切换线程/文件在这种情况下。
答案 3 :(得分:2)
我想说一个线程就足够了。 CPU可能能够运行多个线程,但硬盘的速度比CPU低许多个数量级。即使运行更多线程使I / O请求更快(我不确定),也不会使硬盘实际读取速度更快。它甚至可能会减慢速度。
答案 4 :(得分:2)
如果它是单个硬盘驱动器,那么您希望最小化搜索时间。因此,只能使用一个线程来读取和写入磁盘。
答案 5 :(得分:2)
正如“C#”标记所暗示的那样,我假设您正在编写托管应用程序来执行磁盘I / O.
在这种情况下,我猜测用户级托管线程的数量是无关紧要的,因为它们不是实际执行磁盘I / O的线程。
据我所知,来自用户级托管线程的磁盘I / O请求将在内核级APC队列中排队,Windows I / O线程将处理它们。
因此,我想说在APC队列中排队的磁盘I / O请求的频率将与您的问题更相关。
我还没有看到任何允许将任何用户任务绑定到Windows I / O线程的.NET线程API。但请注意,我的回答是基于以下链接Windows I/O threads vs. managed I/O threads中的相对旧信息。
如果有人知道当前的Windows 7线程池模型与链接中的信息不同,请分享信息以便教育我。
此外,您可能会发现以下链接有助于理解Windows文件I / O操作:Synchronous and Asynchronous I/O
答案 6 :(得分:1)
许多答案都是指HDD的数量。请记住,它还取决于控制器的数量。有时两个硬盘驱动器由单个控制器管理。 另外:同一个硬盘上的两个分区不是两个硬盘驱动器!