Я пишу программу на C, которая читает из стандартного ввода и пишет в стандартный вывод. Но он буферизует данные так, что запись выполняется только после того, как он читает определенное количество байтов (= SIZE)
#include<stdio.h>
#include<stdlib.h>
#define SIZE 100
int main()
{
char buf[SIZE];
int n=0;
//printf("Block size = %d\n", BUFSIZ);
while( ( n = read(0, buf, sizeof(buf)) ) > 0 )
write(1, buf, n);
exit(0);
}
Я запускаю эту программу на Ubuntu 18.04, размещенной в Oracle Virtual Box (4 ГБ ОЗУ, 2 ядра), и тестирую программу на различные значения размера буфера. Я перенаправил стандартный ввод из файла (который содержит случайные числа, создаваемые динамически) и стандартный вывод для перехода в / dev / null. Вот сценарий оболочки, используемый для запуска теста:
#!/bin/bash
# $1 - step size (bytes)
# $2 - start size (bytes)
# $3 - stop size (bytes)
echo "Changing buffer size from $2 to $3 in steps of $1, and measuring time for copying."
buff_size=$2
echo "Test Data" >testData
echo "Step Size:(doubles from previous size) Start Size:$2 Stop Size:$3" >>testData
while [ $buff_size -le $3 ]
do
echo "" >>testData
echo -n "$buff_size," >>testData
gcc -DSIZE=$buff_size copy.c # Compile the program for cat, with new buffer size
dd bs=1000 count=1000000 </dev/urandom >testFile #Create testFile with random data of 1GB
(/usr/bin/time -f "\t%U, \t%S," ./a.out <testFile 1>/dev/null) 2>>testData
buff_size=$(($buff_size * 2))
rm -f a.out
rm -f testFile
done
Я измеряю время, затрачиваемое на выполнение программы, и записываю ее в таблицу. Тестовый запуск выдает следующие данные:
Test Data
Step Size:(doubles from previous size) Start Size:1 Stop Size:524288
1, 5.94, 17.81,
2, 5.53, 18.37,
4, 5.35, 18.37,
8, 5.58, 18.78,
16, 5.45, 18.96,
32, 5.96, 19.81,
64, 5.60, 18.64,
128, 5.62, 17.94,
256, 5.37, 18.33,
512, 5.70, 18.45,
1024, 5.43, 17.45,
2048, 5.22, 17.95,
4096, 5.57, 18.14,
8192, 5.88, 17.39,
16384, 5.39, 18.64,
32768, 5.27, 17.78,
65536, 5.22, 17.77,
131072, 5.52, 17.70,
262144, 5.60, 17.40,
524288, 5.96, 17.99,
Я не вижу каких-либо существенных изменений в времени пользователя и системы, поскольку мы используем другой размер блока. Но теоретически, когда размер блока становится меньше, генерируется много системных вызовов для одного и того же размера файла, и выполнение должно занять больше времени. Я видел результаты теста в книге Ричарда Стивенса «Расширенное программирование в среде Unix» для аналогичного теста, которая показывает, что время пользователя и системы значительно сокращается, если размер буфера, используемого в копии, близок к размеру блока. (В моем случае, размер блока составляет 4096 байт в разделе ext4)
Почему я не могу воспроизвести эти результаты? Я пропускаю некоторые факторы в этих тестах?