我想知道为什么系统在将大量数据写入磁盘时会变慢。
我认为系统变慢应该是CPU有问题。但写入仅受 I/O 限制。
写数据时会发生硬件中断吗?如果是这样,可能是因为中断的原因,CPU一直在进行上下文切换。
答案1
背后的核心原因是通常的:I/O 是很多比 CPU/RAM 慢。即使执行 I/O 操作的进程使用 DMA(这会减轻 CPU 的负载),在某些时候它们也可能需要等待请求的完成。
在最常见的硬盘驱动器情况下,只需添加几个尝试访问分散在驱动器周围的文件的应用程序,您就可以给自己泡一杯咖啡(茶,等等)。使用SSD,情况会变得更好,但即使是SSD - 在SATA上测量的吞吐量为数百MB/s(与旋转盘HDD的数十MB/s相比),并且寻道时间实际上可以忽略不计(与毫秒级相比)旋转板) - 可能成为瓶颈。
据我了解,问题不仅在于数据传输本身,还在于必要的开销 - I/O 由内核控制,但在没有用户空间的情况下很少发生。因此,仅从等待 I/O 的应用程序检查是否发生某些事情(当然取决于实现)就可以进行大量上下文切换。在磁盘传输的情况下,很可能有多个内核线程竞争资源或忙等待(有时这是适当的策略)。请记住,例如,将数据从一个分区复制到另一个分区需要现代文件系统来:找出源数据的位置,读取它,在目标文件系统上分配空间,写入元数据,写入数据,重复直到完成。
如果在某个时刻,您的系统开始交换(通常比常规 I/O 具有更高的优先级),灾难就结束了。
编辑:在与一些 Linux 内核开发人员交谈后,情况变得更加清晰了。主要问题是 I/O 调度程序,它不太清楚要优先考虑哪个 I/O。因此,任何用户输入和随后的图形输出都与磁盘/网络活动共享队列。因此,当它断定可以在其他 I/O 上更有效地使用页面缓存时,也可能会丢弃页面缓存中缓存的进程数据(例如加载的库)。这当然意味着一旦需要再次运行该代码,就必须再次从可能已经处于重负载状态的磁盘中获取它。
也就是说,就 Linux 内核而言,其中许多问题最近已得到修复(问题已已知),所以说 4.4.x 或 4.5.x应该表现比以前更好,并且应该报告问题(通常,当有人想要通过错误报告和测试提供帮助时,内核人员会很高兴)。
答案2
我的经验是,仅 I/O 活动不会减慢系统速度。当其他任务也需要 I/O 时,就会出现这种效果。如果系统正在交换(被迫)并且导致 I/O 负载过重,情况将变得非常糟糕。
您可以通过 影响 I/O 繁重任务的影响ionice
。如果您将它们放在idle
优先位置,那么其他任务的延迟可能仍会增加,但不会超过最小值。如果另一个(非空闲)任务有 I/O 任务要做,则 I/O 任务会立即中断。如果您使用的调度程序支持这些设置。