Perl:написать тайну скорости?
Как скорость вывода может быть выше, чем скорость записи на жесткий диск?
обновление 1: Я изменил следующее:
выключил антивирус. Никакое изменение.
вставлен новый физический диск и используется первый раздел для испытания. (Диск для первоначального теста на последний раздел, отдельный от системного раздела, но на том же физическом диске.). Результат: есть то же самое циклическая картина, но система больше не не отвечает в ходе проверки. Скорость записи несколько выше (может быть, из-за использования первого разделение и / или отсутствие помех системе раздел.) Предварительный вывод: был какой-то помех от системного раздела.
установлен 64 бит Perl. Циклы ушли и все стабильно на 2-секундной шкале времени: 55% CPU on одиночный сердечник, пишет скорость около 65 MB / s.
пробовал на оригинальном диске с 64-битным Perl. Результат: где-то посередине. Циклы 8 секунд, процессор 20-50%, 35 - 65 МБ/сек (вместо глубокого цикла 0-100%, 0 - 120 МБ/сек). Система лишь слегка не реагирует. Скорость записи составляет 50 МБ / сек. Это подтверждает теорию интерференции.
промывка в скрипте Perl. Еще не пробовал.
хорошо, я прошел мимо первый шаг. Я написан на Perl скрипт, который может генерировать очень большой текстовый файл (например, 20 ГБ) и по сути, это всего лишь ряд:
print NUMBERS_OUTFILE $line;
где $line-длинная строка с "n " в конце.
при запуске скрипта Perl скорость записи составляет около 120 МБ/с (согласовано между тем, что вычисляется скриптом, Процесс Explorer и "IO пишет байты / sec" для процесса Perl в мониторе производительности.) и 100% CPU на одном ядре бежит дальше. Эта ставка, I верю, выше, чем пишу скорость жесткого диска.
затем через некоторое время (например, 20 секунд и 2.7 GB написано) вся система становится очень невосприимчивой, и CPU падает до 0%. Это длится, например, 30 секунд. Средняя скорость записи над этими 2 участками последователен с скоростью записи жесткий диск. Времена и размеры, упомянутые в этом пунктом варьируется от запуска к запуску. Диапазон 1 ГБ до 4.3 GB для первого этапа наблюдалось до сих пор. Вот это стенограмма для запуска с 4.3 GB.
существует несколько из этих циклов для текстового файла 9.2 GB генерируется в тесте:
что происходит?
полное Perl script и скрипт драйвера BAT (HTML отформатирован с pre tag). Если две переменные среды MBSIZE и OUTFILE настроены, тогда скрипт Perl должен иметь возможность запускать без изменений на других платформах, чем Окна.
платформа: Perl 5.10.0 от ActiveState; (первоначально 32 бит, позже 64 бит); построить 1004. Windows XP x64 SP2, нет файла страницы, 8 ГБ оперативной памяти, четырехъядерный процессор AMD, 500 ГБ зеленых жестких дисков икры (скорость записи 85 МБ/с?).
4 ответов
Я со всеми, кто говорит, что проблема заключается в заполнении буферов, а затем в их опустошении. Попробуйте включить автосброс чтобы избежать наличия буфера (в 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)
}
}
буферы могут быть хорошими, если вы собираетесь немного печатать, работать, печатать Литт, делать какую-то работу и т. д. Но если вы просто собираетесь взрывать данные на диск, они могут вызвать странное поведение. Вам также может потребоваться отключить кэширование записи в файловой системе.
все данные кэшируются в буферах перед эффективной укладкой на физический диск. Буфер из системы, другой внутри самого диска (вероятно, буфер 32MB). Пока вы заполняете эти буферы, ваша программа работает на полной скорости и 100% CPU. Как только буферы заполнены, ваша программа ждет диска, который намного медленнее, чем память и буферы, и это ожидание заставляет вас прекратить потреблять весь этот процессор.
возможно, вы можете сделать свой код "ждать диска" из начните, используя некоторый Perl, эквивалентный fflush()
.
возможно, ОС записывает на диск так быстро, как может (85 Мб/с), и помещает лишние 35 МБ/с в буфер, и когда он заполняется, приостанавливает приложение, чтобы очистить буфер. Поскольку буфер сливается со скоростью 85 Мб / с, вы ожидаете, что он займет 35/85 = ~0,4 раза больше времени для слива, чем для заполнения. Это в целом совместимо с вашим графиком, если я достаточно прищурюсь.
вы можете оценить размер буфера как произведение времени паузы и скорости диска.
посмотрите на график! Зеленая линия указывает среднюю длину очереди диска. В какой-то момент он получает пик, а затем процессор переходит в 0. IO пишет также идет в 0. Он возвращается к норме, пока не будет показан второй пик. Затем CPU и IO пишут возврат к нормальному. Затем и IO и CPU снова падают, чтобы снова подняться на следующий пик очереди. И снова вниз, и снова вверх...
возможно, в этот момент диск выполняет физическую запись. Однако также может оказаться, что в этот момент система выполняет проверку диска, считывая данные, которые она только что написала, чтобы проверить записи, убедившись, что данные записаны правильно.
еще одна вещь, которую я замечаю, - это размер 2.7 GB. Поскольку вы запускаете это в системе Windows, я становлюсь немного подозрительным, так как это касается объема памяти, который может обрабатывать Windows, как 32-битный процесс. 64-битные окна обеспечат приложение до 3 ГБ ОЗУ (немного меньше), но затем ему нужно снова выпустить его. Вы можете хотите использовать Process Explorer для проверки количества используемой ОЗУ и количества считываний ввода-вывода.
и, возможно, использовать 64-битную версию Perl...