C# 磁盘群集/块大小与二进制文件读取的相关性如何?

C# 磁盘群集/块大小与二进制文件读取的相关性如何?,c#,.net,file,C#,.net,File,我有一些非常大的二进制文件(每个大于1TB),其中包含高度压缩的数据。我经常从这些文件中读取大约300字节的数据块。为此,我一次在7个线程中打开文件并执行读取操作 磁盘群集大小如何与此对应。当我读取300字节且磁盘群集大小设置为64KB时,.net会读取整个64KB而不是300字节吗 对于这种情况,较小的集群大小还是较大的集群大小更好? 我使用FileStream,将FileOptions设置为FileOptions.RandomAccess。是的,您将从磁盘上读取64kb的数据块。较小的集群大

我有一些非常大的二进制文件(每个大于1TB),其中包含高度压缩的数据。我经常从这些文件中读取大约300字节的数据块。为此,我一次在7个线程中打开文件并执行读取操作

磁盘群集大小如何与此对应。当我读取300字节且磁盘群集大小设置为64KB时,.net会读取整个64KB而不是300字节吗

对于这种情况,较小的集群大小还是较大的集群大小更好?
我使用FileStream,将FileOptions设置为FileOptions.RandomAccess。

是的,您将从磁盘上读取64kb的数据块。较小的集群大小将为您提供更快的小范围读取。它有更多文件碎片的风险(可能不是一个问题)

但是,通过降低集群大小,您无法获得更大的吞吐量。在磁盘执行查找操作并获取数据时,它可能已经读取了大约1MB的数据。从64kb增加到4kb只节省了很少的内存。您节省的时间约为磁盘搜索所用时间的20分之一。

很简单:


集群大小越小,延迟(延迟)越低,但吞吐量(总体平均数据速率)也越低

如果要在运行时优化从任何给定分区读取的缓冲区大小,可以更进一步,在运行时获取集群大小,并将其倍数用于读取缓冲区

但是,要做到这一点,您需要从kernel32.dll使用PInvoke

使用GetDiskFreeSpace函数获取给定分区的群集大小

以下是方法签名:

[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)]
   static extern bool GetDiskFreeSpace(string lpRootPathName, 
   out uint lpSectorsPerCluster, 
   out uint lpBytesPerSector, 
   out uint lpNumberOfFreeClusters, 
   out uint lpTotalNumberOfClusters);
将路径传递给您感兴趣的驱动器的根目录。 要获得每个群集的字节数,请将lpSectorsPerCluster乘以lpBytesPerSector

有关更多信息,请访问pinvoke.com页面了解此功能:

较小的群集规模根本不会导致吞吐量降低。@usr:是的,因为开销较大。(它只影响随机读取而不是顺序读取。)相反,如果有影响,它会对顺序操作产生更大的影响。小型集群仅有的两个影响是更多的分配开销和更多的碎片。碎片伤害的是顺序访问,而不是随机访问。@usr:你是对的,我说的是错的——因为我说的不是我的意思。当我说“随机读取”时,我指的是磁盘的“随机”,而不是文件系统的“随机”。i、 e.如果集群的大小较小,那么当数据碎片化时,磁盘的随机读取会使每次寻道的数据量减少,因此会对您造成伤害。但我的措辞相当糟糕,我同意\