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

Chr*_*ris 13 .net c# file-io binary-data

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

现在我有一些想要读取该文件部分的线程.每个线程都有一个所需的块数组.每个块都通过文件偏移(位置)和大小(大多数约300个字节)来寻址.

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

由于文件是高度压缩的,将随机访问,我确切地知道位置,我没有其他方法来优化它.

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

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

Eug*_*eck 4

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

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

为什么要同步读取?它们的延迟低于异步读取。为什么要在队列上浪费延迟?一个好的无锁队列实现的启动延迟小于 10ns,远少于两个线程切换

更新:一些问答

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

您会使用带有 FileOptions.RandomAccess 的 FileStream 吗?是的

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