参考此页面:https://support.microsoft.com/en-us/kb/140365
NTFS 在卷超过 16 TB 之前不会超过 4KB 簇大小,而在现代版本的 Windows 上,FAT32 在 16GB–32GB 卷范围内的最大簇大小为 16KB。
但是 exFAT 仅在 7MB 至 256MB 容量范围内默认为 4KB。之后,它会在 256MB 至 32GB 范围内跳转到 32KB,超过此范围则跳转到 128KB。
为什么会这样?相对较高的簇大小似乎是一种浪费,尤其是在为较小的外部设备(如闪存驱动器)设计的格式中。如果你正在格式化闪存,情况就更是如此,因为据我所知,较大的簇大小的主要好处是由于碎片更少、需要读取的整体簇更少而导致的 IO 速度更快。如果我错了,请纠正我,但闪存更不容易因碎片而导致速度变慢。那么为什么要把簇大小设得这么高呢?
答案1
因为 exFAT 主要用于大容量 SD 卡之类的东西,而在 SD 卡上,您必须先擦除一个扇区,然后才能写入数据。如果在具有较大擦除扇区大小的卡上使用小簇,则会导致对同一扇区执行许多擦除和写入命令,将几个连续簇的数据写入磁盘,这不仅会降低性能,还会过早磨损闪存单元。擦除扇区大小通常不会记录在卡数据表中,但可以在卡的 CSD 寄存器中找到。此寄存器的内容将因卡的内部设计而异。由于 SD 卡通常用于存储大文件的相机之类的东西,所以大簇大小的浪费空间并不重要,并且只有当您存储大量非常小的文件时才会如此,而这通常不会发生。
该网页包含大约十几张卡片的该寄存器的内容:
http://goughlui.com/2014/01/03/project-read-collect-decode-sd-card-csd-register-data/
如果您将其内容输入到以下计算器中,您会发现对于一些 32/64GB 卡,擦除扇区大小为 128 个块,每个块为 512 字节。对于 2GB 卡,擦除扇区大小为 32 个块,每个块为 1024 字节。
http://goughlui.com/static/csdecode2.htm
Windows 是否足够智能,能够查询 CSD 寄存器并建议簇大小,或者它是否只是根据分区或磁盘大小进行猜测,目前尚不清楚。如果您使用微控制器模拟 SD 卡,您就能找到答案。
答案2
之前对这个问题的回答是错误的,不应该被赞成或接受。exFAT 不是一个闪存文件系统。它从未直接用于“原始”闪存。即使簇大小与闪存擦除块大小匹配,这也将极其低效。
实际情况是,exFAT 在块设备模拟层上运行,该层通常在闪存设备本身的固件中实现。假设 exFAT 簇大小为 128K,(假)块设备的扇区大小为 4K,并且您将 5K 文件写入 exFAT 卷。exFAT 驱动程序分配该文件的大小为 128K,但(忽略元数据)它仅写道8K:实际包含文件数据的两个扇区。如果簇大小为 4K,则写入的数据量相同。不同之处在于,如果您写入一堆 5K 文件,它们将被 30 个从未读取或写入的未使用的假扇区隔开。但这并不重要,因为数据在原始闪存上的实际位置与虚拟块设备的扇区号无关。exFAT 簇大小可能对写入原始闪存的数据量或块擦除操作的数量影响不大。当您包括 exFAT 元数据开销时,更大的簇应该会更高效 - 但这与原始闪存的擦除块的大小无关,后者完全被模拟层隐藏。
当然,如果您尝试存储大量小文件,那么大簇意味着您在伪块设备上的空间会用尽,并且没有办法强迫模拟层让您使用其余的真实空间(除非使用您跳过的那些扇区号),因此大簇似乎仍然是一个坏主意。我不知道微软的谁决定默认的 exFAT 簇大小应该这么大,或者为什么,但我会猜测。
exFAT 的每簇开销比 NTFS 大得多:实际上大 65 倍,因为 NTFS 的可用空间位图每簇只有一个位,而 exFAT 在位图中有一个位,另外两个 FAT 各有 4 个字节。另一方面,NTFS 还有一些其他重要的固定开销(特别是日志的几兆字节),这些开销与簇数没有直接关系。
我猜他们想让 exFAT 的开销看起来比 NTFS 少。在小卷上,NTFS 总是至少消耗几兆字节,因此 4K 簇的 0.2% 开销似乎并不那么糟糕。但是,新格式化的 1TB 卷将具有大约 2GB 的 exFAT 元数据和 4K 簇,而 NTFS 只需要大约 40MB。这看起来很糟糕(我想确实很糟糕),所以他们不得不使用更大的簇大小。