我注意到,每当我将大文件从用作系统驱动器的 SSD 复制或移动到 HDD 或外部硬盘或闪存驱动器时,Windows 显示的速度图表总是相同的:传输速度从大约 450 MB/s 开始,几秒钟后下降到 90 到 130 MB/s 之间的某个值,并保持稳定,直到复制/移动操作结束。
这激起了我的好奇心,所以我决定弄清楚这是什么原因造成的。我的一些想法如下:
也许这就是实际传输的速度
不确定。虽然 450 MB/s 的速度与我的 SSD 的额定速度相匹配,但考虑到我在后台还进行了一些其他磁盘读取/写入,7200 rpm 硬盘不可能跟上它的速度,因为我稍后获得的 130 MB/s 速度也是我能期望的最高速度。那么,额外的数据去哪里了?
额外的数据被存储在硬盘的缓存中
这有点道理,但如果考虑到更高传输速度的持续时间,我的硬盘缓存必须超过 3 GB,而事实肯定不是这样。还能是什么呢?
额外的数据被存储在 RAM 中
这很有道理。我的 RAM 是系统中唯一可以与 SSD 速度匹敌的部分,而且我有足够的 RAM。让我们来验证一下这个理论!
我打开任务管理器,查看“性能”选项卡。内存使用率稳定在 3.7 GB。然后我开始另一个 15 GB 的文件传输。内存使用率开始上升,并在传输速度降至 130 MB/s 时停止在 5.3 GB。它保持不变,直到文件传输结束(传输对话框关闭),然后慢慢降回传输前的 3.7 GB 水平。
所以,我的最后一个理论是正确的。进一步的证实是,额外使用的内存被标记为Modified
。
重点是什么?
我的问题是,这样做的目的是什么?虽然我不介意将部分 RAM 用于文件传输,因为即使在我最繁忙的多任务处理过程中,我也从未见过它的使用率超过 70%,但将 1.6 GB 的数据(您不会对其进行任何处理)存储在 RAM 中有什么好处呢?
从数据完整性的角度来看,我看不到任何好处,因为您只是复制文件,并且在发生电源故障的情况下,RAM 或 HDD 都无法特别成功地保留传输中的数据。
我可以看到的好处是源磁盘(SSD)可以快速释放,这样如果另一个进程需要在其上执行大量读/写操作,它可以在不受文件传输阻碍的情况下进行,但如果是这种情况,为什么不继续以最大速度将所有 15 GB 加载到内存中呢?
此外,此过程还会误导用户,因为文件传输即使在传输对话框关闭后仍会继续进行,因为部分数据仍在从内存复制到硬盘。这可能会导致用户在数据仍在写入时拔出可移动驱动器,从而可能损坏可移动驱动器,因为并不是每个人都愿意安全地移除硬件。
请记住,我还没有对可移动驱动器进行彻底的测试,因为 Windows 可能会以不同的方式处理它们,从而使我的最后一点无效。
答案1
Windows 内存管理很复杂。如你所见,它在不同设备上有不同的行为。
不同的操作系统有不同的内存管理。
你的问题很有趣。我正在分享一个MSDN 页面它解释了 Windows 中的部分内存管理,更具体地说“映射文件”
它是软件开发人员的文档,但 Windows 也是软件。
使用 MMF I/O 的一个优点是系统以 4K 数据页执行所有数据传输。虚拟内存管理器 (VMM) 负责管理所有内存页面。它决定何时将页面分页到磁盘、哪些页面可供其他应用程序使用,以及每个应用程序在整个物理内存分配中可以拥有多少页面。由于 VMM 以相同的方式执行所有磁盘 I/O(每次读取或写入一页内存),因此它已进行优化以使其尽可能快。将磁盘读写指令限制为 4K 页面序列意味着几个较小的读取或写入被有效地缓存到一个较大的操作中,从而减少了硬盘读/写头移动的次数。一次读取和写入内存页面有时被称为分页,这在虚拟内存管理操作系统中很常见。
不幸的是,我们无法轻易弄清楚微软如何实现读/写 - 它不是开源的。
但我们知道它有非常不同的情况:
From To
==================
SSD HDD
HDD Busy SSD ??
NTFS FAT
NTFS ext4
Network HDD
IDE0slave IDE0master // IDE cable support disk to disk transfer.
IDE SATA // in this case you have separated device controllers.
你明白了... 硬盘可能很忙,文件系统可能不同(或可能相同)...
例如:dd
Linux 中的命令“逐字节”复制数据 - 它非常快(因为两个硬盘的磁头移动同步),但如果文件系统不同(例如具有不同的块大小) - 复制的数据将无法读取,因为文件系统具有不同的结构。
我们知道 RAM 比 HDD 快得多。因此,如果我们必须进行一些数据解析(以适应输出文件系统),最好将这些数据放在 RAM 中。
再想象一下你直接从文件复制到文件。
如果你用其他数据流使源超载会发生什么?目的地呢?
如果你此刻几乎没有可用的 RAM 怎么办?
...
只有微软工程师知道。
答案2
为什么驱动器之间的文件传输使用 RAM?
因为 I/O 操作(几乎总是)在外设和 RAM 之间进行。
因此文件复制实际上是两个磁盘操作:读取(到 RAM),然后写入(从 RAM)。
某些系统可以执行外设到外设的操作(因此不需要 RAM 中的缓冲区)。我见过可以执行驱动器到驱动器传输的 SCSI 主机适配器(通过使用板载处理器和 RAM/FIFO,无需 CPU 和 RAM 的参与)。我见过可以执行外设到外设传输的 DMA 控制器。这些是例外,不是规则,也不是常用的。
请注意,使用外设到外设的传输时,错误处理会变得更加复杂,因此即使硬件可用,操作系统也很少将其用于任意 I/O 操作。
我的问题是,这样做的目的是什么?
源数据(正在读取/复制的文件)必须读入 RAM,因为这是计算机架构的本质(结合使用 DMA)。
在 RAM 稀缺且操作系统还不那么复杂的时代,典型的选择是使用尽可能小的缓冲区(例如只有一个扇区或块)或可以优化速度的缓冲区(例如多扇区传输)来执行这些传输。
如今,有了相对较大的内存和复杂的算法,典型的操作系统将尝试使用任何/所有空闲/未使用的内存作为缓冲区来读取此源数据。
在将源数据写入目标后,可以丢弃该数据。但如果没有对该内存的需求(即它将保持未使用状态),则没有必要丢弃该数据。
如果已对数据进行标记或编目以识别其来源文件,则可以缓存该数据以供重复使用。
请注意,此文件缓存本质上是免费的;获取此缓存时,操作系统无需承担额外的 I/O 负担。唯一的成本是维护内容目录,当缓存命中时可以对其进行偏移(并节省重新读取的 I/O)。
因此,缓存文件是正常读取这些文件的一个免费结果。它会暂时使用本来闲置和未使用的内存。操作系统维护此缓存的开销通常很小,并且会在缓存命中时得到回报。
此外,这个过程会误导用户,因为即使在传输对话框关闭后,文件传输仍会继续进行,因为一些数据仍然从内存复制到硬盘上。
这是系统对用户的可用性与保证写入之间的权衡。
可以编写一个程序来执行阻塞同步写入,这将等待每个物理写入操作完成后再继续执行程序。或者,在适当的时间点,程序可以通过调用同步()或类似的系统调用。
在写入(或复制)操作中,现代操作系统会尝试在所有写入操作至少排队后立即让用户使用(这意味着它们可能尚未完成)。
这有利于多任务处理。如果您想做其他甚至不涉及该驱动器的事情,为什么您必须等待该驱动器上的操作完成后才能做其他事情?
权衡是您必须是一位受过教育的用户,并意识到(存储)设备需要正确卸载。
此可用性功能与上面提到的文件缓存功能无关。如果可用/可能,您可以禁用其中一个而不影响另一个。
笔记
如果满足以下条件,数据传输可以不使用 RAM 缓冲区:
1. 对输入和输出操作执行编程 I/O(使用 CPU),
和
2. 输入和输出具有匹配的数据传输速率和传输大小,
和
3. 两个设备都是字符型的,而不是块设备。(这将排除磁盘驱动器。)
然而,当 DMA 或总线主控可用时,操作系统很少会选择使用编程 I/O,也不太可能被编程来处理成对输入+输出传输的双重复杂性。