Perl:写速度之谜?

Pet*_*sen 9 perl performance hard-drive

输出速率如何高于硬盘写入速率?

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

  1. 关掉杀毒软件.没变.

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

  3. 安装64位Perl.循环消失,一切都在2秒的时间范围内保持稳定:单核上55%的CPU,写入速度约为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;
Run Code Online (Sandbox Code Playgroud)

其中$ line是一个长字符串,末尾带有"\n".

当Perl脚本启动时,写入速率大约为120 MB/s(在脚本,Process Explorer和"性能监视器"中的进程Perl的"IO写入字节数/秒" 之间保持一致 .)和单核上的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位); 构建1004.Windows XP x64 SP2,没有页面文件,8 GB RAM,AMD四核CPU,500 GB绿色鱼子酱硬盘(写入速度85 MB/s?).

Hav*_*ard 5

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

也许你可以从一开始就使你的代码"等待磁盘",使用一些相当于的Perl fflush().

  • 在Linux系统上,缓冲区通常配置为扩散到几乎所有空闲RAM. (4认同)

Cha*_*ens 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)
    }
}
Run Code Online (Sandbox Code Playgroud)

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