9

输出速率怎么可能高于硬盘写入速率?

更新 1:我更改了以下内容:

  1. 关闭了杀毒软件。不用找了。

  2. 插入新的物理磁盘并使用第一个分区进行测试。(初始测试的磁盘在最后一个分区上,与系统分区分开,但在同一个物理磁盘上。)。结果:存在相同的循环模式,但系统在测试期间不再无响应。写入速度稍高(可能是由于使用了第一个分区和/或不再干扰系统分区)。初步结论:系统分区存在某种干扰。

  3. 安装 64 位 Perl。周期消失了,一切都在 2 秒的时间范围内稳定:单核 CPU 占 55%,写入速度约为 65 MB/s。

  4. 使用 64 位 Perl 在原始驱动器上进行了尝试。结果:介于两者之间。周期为 8 秒,CPU 20-50%,35 - 65 MB/秒(而不是 0-100%,0 - 120 MB/秒的深度周期)。系统只是轻微反应迟钝。写入速度为 50 MB/秒。这支持了干涉理论。

  5. 在 Perl 脚本中刷新。还没试过。


好的,我通过了第一关。我编写了一个 Perl 脚本,它可以生成一个非常大的文本文件(例如 20 GB),并且基本上只是一些:

print NUMBERS_OUTFILE $line;

其中 $line 是一个以“\n”结尾的长字符串。

当 Perl 脚本启动时,写入速率约为 120 MB/s(与脚本、 Process Explorer和 Performance Monitor 中进程 Perl 的“IO Write Bytes/sec”计算的结果一致)和 100% CPU 在单核上它正在运行。我相信这个速度比硬盘的写入速度要高。

然后在一段时间后(例如 20 秒和 2.7 GB 写入)整个系统变得非常无响应并且 CPU 下降到 0%。这持续例如30秒。这两个阶段的平均写入速度与硬盘的写入速度一致。本段中提到的时间和大小因运行而异。到目前为止,已观察到第一阶段的范围为 1 GB 到 4.3 GB。这是运行 4.3 GB 的成绩单

测试中生成的 9.2 GB 文本文件有几个这样的周期:

在此处输入图像描述

到底是怎么回事?


完整的Perl 脚本BAT 驱动程序脚本(使用 pre 标签格式化的 HTML)。如果设置了两个环境变量 MBSIZE 和 OUTFILE,那么 Perl 脚本应该能够在 Windows 以外的其他平台上不加改变地运行。

平台:来自 ActiveState 的 Perl 5.10.0;(最初是 32 位,后来是 64 位);build 1004。Windows XP x64 SP2,无页面文件,8 GB RAM,AMD 四核 CPU,500 GB Green Caviar 硬盘(写入速度 85 MB/s?)。

4

4 回答 4

5

所有数据在被有效地放置在物理磁盘中之前都缓存在缓冲区中。一个来自系统的缓冲区,另一个位于磁盘本身的缓冲区(可能是 32MB 的缓冲区)。当您填充这些缓冲区时,您的程序会以全速和 100% CPU 运行。一旦缓冲区已满,您的程序就会等待磁盘,这比内存和缓冲区慢得多,而且这种等待使您停止消耗所有这些 CPU。

也许你可以让你的代码从一开始就“等待磁盘”,通过使用与fflush().

于 2009-09-07T21:39:09.947 回答
5

我和其他所有说问题是缓冲区填充然后清空的人一样。尝试打开autoflush以避免有缓冲区(在 Perl 中):

#!/usr/bin/perl

use strict;
use warnings;

use IO::Handle;

my $filename = "output.txt";

open my $numbers_outfile, ">", $filename
    or die "could not open $filename: $!";

$numbers_outfile->autoflush(1);

#each time through the loop should be 1 gig
for (1 .. 20) {
    #each time though the loop should be 1 meg
    for (1 .. 1024) {
        #print 1 meg of Zs
        print {$numbers_outfile} "Z" x (1024*1024)
    }
}

如果您要打印一点,做一些工作,打印一点,做一些工作等,缓冲区可能会很好。但是如果您只是要将数据爆破到磁盘上,它们可能会导致奇怪的行为。您可能还需要禁用文件系统正在执行的任何写入缓存。

于 2009-09-08T01:43:12.597 回答
4

也许操作系统正在尽可能快地写入磁盘(85 MB/s),并将多余的 35 MB/s 放入缓冲区,当它填满时,正在暂停应用程序以刷新缓冲区。由于缓冲区以 85 MB/s 的速度排空,因此您预计排空时间是填充时间的 35/85 = ~0.4 倍。如果我足够眯眼的话,这与您的图表大致兼容。

您可以将缓冲区的大小估计为暂停时间和磁盘速度的乘积。

于 2009-09-07T21:44:14.787 回答
3

看图表!绿线表示平均磁盘队列长度。在某一时刻,它达到一个峰值,然后 CPU 变为 0。IO Writes 也变为 0。它会恢复正常,直到显示第二个峰值。然后 CPU 和 IO 写入恢复正常。然后 IO 和 CPU 再次下降,在下一个队列峰值再次上升。又跌了,又涨了……

可能是磁盘当时正在执行物理写入。但是,也可能是系统当时正在执行磁盘验证,读取它刚刚写入的数据以验证写入,确保数据写入正确。

我注意到的另一件事是 2.7 GB 大小。由于您在 Windows 系统上运行它,我变得有点怀疑,因为这是关于 Windows 可以处理的内存量,作为 32 位进程。64 位 Windows 将为应用程序提供高达 3 GB 的 RAM(少一点),但随后需要再次释放它。您可能希望使用 Process Explorer 检查正在使用的 RAM 量和 IO 读取量。

也许使用 64 位 Perl 版本...

于 2009-09-07T22:43:07.550 回答