通过文件偏移从2TB文件中随机读取多个300字节块的最快方法?

时间:2012-01-17 16:04:12

标签: c# .net file-io binary-data

我在RAID 5(4 x 7.2k @ 3TB)系统上有一些2TB只读(没有写入一次)文件。

现在我有一些想要读取该文件部分的线程。 每个线程都有一个所需的块数组。 每个块都由文件偏移量(位置)和大小(大多数约300个字节)进行寻址,以便从中读取。

读取此数据的最快方法是什么。 我不关心CPU周期,(磁盘)延迟是重要的。 所以,如果可能的话,我想利用硬盘的NCQ。

由于文件是高度压缩的,并且会随机访问,我确切地知道位置,我没有其他方法可以优化它。

  • 我应该将文件读取汇集到一个线程吗?
  • 我应该保持文件打开吗?
  • 每个线程(可能大约30个)是否应该同时打开每个文件,新的线程是什么(来自Web服务器)?
  • 如果我等待100毫秒并按文件偏移(最低的第一个)排序我的读数会不会有帮助?

阅读数据的最佳方法是什么?你有经验,技巧,提示吗?

3 个答案:

答案 0 :(得分:4)

并行请求的最佳数量在很大程度上取决于应用程序之外的因素(例如,磁盘计数= 4,NCQ深度= ?,驱动程序队列深度=?...),因此您可能希望使用可以适应的系统或改编。我的建议是:

  • 将所有读取请求与允许通知请求线程的一些元数据一起写入队列
  • 有N个线程从该队列出队,同步读取块,通知请求线程
  • 使N可运行时更改
  • 由于您不关心CPU,您的工作线程可以计算浮动延迟平均值(和/或最大值,具体取决于您的需求)
  • 向上和向下滑动N,直至达到甜蜜点

为什么同步读取?它们的延迟低于ascync读数。 为什么要在队列上浪费延迟?一个好的无锁队列实现从低于10ns的延迟开始,远低于两个线程开关

更新:部分问答

读取线程是否应该保持文件打开? 是的,绝对是这样。

您是否会将FileStream与FileOptions.RandomAccess一起使用?的

你写“同步读取块”。这是否意味着每一个读取线程一旦出现读取块的顺序,就应该开始从磁盘读取一个块? 是的,这就是我的意思。读取请求的队列深度由线程数管理。

答案 1 :(得分:0)

磁盘是“单线程”,因为只有一个磁头。无论你使用多少线程,它都不会更快......事实上,更多的线程可能只会减慢速度。只需获取列表并在应用程序中安排(排序)。

你当然可以使用许多使用NCQ的线程可能更有效,但是在应用程序中安排它并使用一个线程应该可以更好地工作。

如果文件碎片化 - 使用NCQ和几个线程,因为您无法知道磁盘上的确切位置,因此只有NCQ可以优化读取。如果它是连续的 - 使用排序。

您也可以尝试直接I / O绕过操作系统缓存并按顺序读取整个文件...有时可能会更快,特别是如果此阵列上没有其他负载。

答案 2 :(得分:0)

ReadFileScatter会做你想做的事吗?