Я читаю файлы разного размера (1 КБ - 1 ГБ), используя read()
в C
. Но каждый раз, когда я проверяю page-faults
с помощью perf-stat
, он всегда дает мне одинаковые (почти) значения.
Моя машина: (fedora 18 на виртуальной машине, ОЗУ — 1 ГБ, место на диске — 20 ГБ)
uname -a
Linux localhost.localdomain 3.10.13-101.fc18.x86_64 #1 SMP Fri Sep 27 20:22:12 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
mount | grep "^/dev"
/dev/mapper/fedora-root on / type ext4 (rw,relatime,seclabel,data=ordered)
/dev/sda1 on /boot type ext4 (rw,relatime,seclabel,data=ordered)
Мой код:
10 #define BLOCK_SIZE 1024
. . .
19 char text[BLOCK_SIZE];
21 int total_bytes_read=0;
. . .
81 while((bytes_read=read(d_ifp,text,BLOCK_SIZE))>0)
82 {
83 write(d_ofp, text, bytes_read); // writing to /dev/null
84 total_bytes_read+=bytes_read;
85 sum+=(int)text[0]; // doing this just to make sure there's
// no lazy page loading by read()
// I don't care what is in `text[0]`
86 }
87 printf("total bytes read=%d\n", total_bytes_read);
88 if(sum>0)
89 printf("\n");
Вывод статистики производительности: (показывает размер файла, время чтения файла и количество ошибок страницы)
[read]: f_size: 1K B, Time: 0.000313 seconds, Page-faults: 150, Total bytes read: 980
[read]: f_size: 10K B, Time: 0.000434 seconds, Page-faults: 151, Total bytes read: 11172
[read]: f_size: 100K B, Time: 0.000442 seconds, Page-faults: 150, Total bytes read: 103992
[read]: f_size: 1M B, Time: 0.00191 seconds, Page-faults: 151, Total bytes read: 1040256
[read]: f_size: 10M B, Time: 0.050214 seconds, Page-faults: 151, Total bytes read: 10402840
[read]: f_size: 100M B, Time: 0.2382 seconds, Page-faults: 150, Total bytes read: 104028372
[read]: f_size: 1G B, Time: 5.7085 seconds, Page-faults: 148, Total bytes read: 1144312092
Вопросы:
1. Как могут быть одинаковыми ошибки страницы для файла read()
размером 1 КБ и 1 ГБ? Поскольку я тоже читаю данные (строка кода № 84), я удостоверяюсь, что данные фактически читаются.
2. Единственная причина, по которой я могу думать, что они не столкнуться с таким количеством отказов страниц из-за того, что данные уже присутствуют в основной памяти. Если это так, как я могу очистить его, чтобы при запуске моего кода он действительно показывал мне истинные ошибки страницы? В противном случае я никогда не смогу измерить истинную производительность read()
.
Edit1:echo 3 > /proc/sys/vm/drop_caches
не помогает, вывод остается прежним.
Edit2: для mmap
вывод perf-stat
:
[mmap]: f_size: 1K B, Time: 0.000103 seconds, Page-faults: 14
[mmap]: f_size: 10K B, Time: 0.001143 seconds, Page-faults: 151
[mmap]: f_size: 100K B, Time: 0.002367 seconds, Page-faults: 174
[mmap]: f_size: 1M B, Time: 0.007634 seconds, Page-faults: 401
[mmap]: f_size: 10M B, Time: 0.06812 seconds, Page-faults: 2,688
[mmap]: f_size: 100M B, Time: 0.60386 seconds, Page-faults: 25,545
[mmap]: f_size: 1G B, Time: 4.9869 seconds, Page-faults: 279,519
bytes_read
? Какое у вас ядро и файловая система? Я думаю, что вы не получаете много ошибок страниц, потому что блокировка sys_read способна управлять страницами без ошибок. Он просто выделяет страницу непосредственно перед записью на нее. Ошибка страницы возникает только при доступе к несопоставленной странице, это ловушка. - person osgx   schedule 27.04.2014