Страницы

Поиск по вопросам

пятница, 12 июля 2019 г.

Что показывает Linux команда /usr/bin/time в поле maxresident?

Linux avp-ubu1 2.6.32-38-generic #83-Ubuntu SMP Wed Jan 4 11:12:07 UTC 2012 x86_64 GNU/Linux
Казалось бы очевидно (из man)
M Maximum resident set size of the process during its life‐ time, in Kilobytes.
Однако, значение, которое я увидел для тестируемой программы, выглядело каким-то несуразно большим.
Написал простой тест, который делает malloc(), memset() и потом free() и распечатал данные по памяти из /proc/self/status в разных точках этой программки.
/usr/bin/time maxresident оказался равен VmHWM * 4 (???) VmHWM: Peak resident set size ("high water mark"). (См. man 5 proc). В принципе если 'kB' после значения VmHWM это количество (в тысячах) 4Kbytes страниц, то похоже. Но (!) уж больно это VmHWM совпадает с количеством байт выделяемых malloc.
Что бы все это значило?
Вывод программки
avp@avp-ubu1:~/src/tst/sort$ gcc mem.c avp@avp-ubu1:~/src/tst/sort$ /usr/bin/time ./a.out 4000000 VmPeak: 4000 kB VmSize: 4000 kB VmLck: 0 kB VmHWM: 508 kB VmRSS: 508 kB VmData: 184 kB VmStk: 88 kB VmExe: 8 kB VmLib: 1640 kB VmPTE: 28 kB start vmsize: 4000
VmPeak: 7912 kB VmSize: 7912 kB VmLck: 0 kB VmHWM: 560 kB VmRSS: 560 kB VmData: 4096 kB VmStk: 88 kB VmExe: 8 kB VmLib: 1640 kB VmPTE: 32 kB malloc 4000000 vmsize: 7912
VmPeak: 7912 kB VmSize: 7912 kB VmLck: 0 kB VmHWM: 4464 kB VmRSS: 4464 kB VmData: 4096 kB VmStk: 88 kB VmExe: 8 kB VmLib: 1640 kB VmPTE: 36 kB memset vmsize: 7912
VmPeak: 7912 kB VmSize: 4004 kB VmLck: 0 kB VmHWM: 4468 kB VmRSS: 556 kB VmData: 188 kB VmStk: 88 kB VmExe: 8 kB VmLib: 1640 kB VmPTE: 28 kB end vmsize: 4004
0.01user 0.00system 0:00.00elapsed 250%CPU (0avgtext+0avgdata 17872maxresident)k 0inputs+0outputs (0major+1157minor)pagefaults 0swaps avp@avp-ubu1:~/src/tst/sort$ avp@avp-ubu1:~/src/tst/sort$

Просто обновил (через 2 недели), может быть кто-нибудь из новичков знает?
=== UPDATE ===
Возьмем простую программку
#include #include #include #include #include
int main (int ac, char *av[]) { char cmd[100]; struct rusage r; getrusage(RUSAGE_SELF, &r); printf("ru_maxrss: %ld
", r.ru_maxrss); sprintf(cmd, "grep Vm /proc/%d/status", (int)getpid()); system(cmd); getrusage(RUSAGE_SELF, &r); printf("ru_maxrss: %ld
", r.ru_maxrss);
return puts("End") == EOF; }
и запустим ее
avp@avp-xub11:hashcode$ ./a.out ru_maxrss: 2544 VmPeak: 2112 kB VmSize: 2024 kB VmLck: 0 kB VmPin: 0 kB VmHWM: 284 kB VmRSS: 284 kB VmData: 32 kB VmStk: 136 kB VmExe: 4 kB VmLib: 1824 kB VmPTE: 16 kB VmSwap: 0 kB ru_maxrss: 2544 End avp@avp-xub11:hashcode$
а теперь запустим ее же через /usr/bin/time
avp@avp-xub11:hashcode$ /usr/bin/time ./a.out ru_maxrss: 280 VmPeak: 2112 kB VmSize: 2024 kB VmLck: 0 kB VmPin: 0 kB VmHWM: 280 kB VmRSS: 280 kB VmData: 32 kB VmStk: 136 kB VmExe: 4 kB VmLib: 1824 kB VmPTE: 16 kB VmSwap: 0 kB ru_maxrss: 280 End 0.00user 0.02system 0:00.07elapsed 30%CPU (0avgtext+0avgdata 840maxresident)k 0inputs+0outputs (0major+583minor)pagefaults 0swaps avp@avp-xub11:hashcode$
В последнем запуске мы видим, что наш Maximum resident set size, полученный из getrusage() равен 280 и совпадает со значением VmRSS из /proc/PID/status.
Однако, в выводе /usr/bin/time мы видим 840. Вот и вопрос, почему???
Кстати, если кто-то обратил внимание, то в первом запуске getrusage() возвращает почему-то совсем другое число (не совпадающее ни с чем в /proc/PID/status ... ), но это уже другой вопрос.


Ответ

что такое maximum resident set size — объясняется вкратце здесь разница в «показаниях» между тем, что выдаёт тестовая программа и тем, что выдаёт программа /usr/bin/time, запускающая тестовую программу, заключается в моменте «снятия показаний»
тестовая программа делает это в процессе своего выполнения, а /usr/bin/time — уже после завершения тестовой программы.
понятно, что в разные моменты времени динамически изменяющаяся величина, характеризующая процесс, может изменяться.

обновление
но столь кардинальное различие (в четыре раза) проистекает из ошибки в исходниках gnu/time
в дистрибутиве debian эта ошибка была исправлена коротким патчем
--- time-1.7.orig/time.c 2011-11-20 17:48:44.000000000 +0000 +++ time-1.7/time.c 2011-11-20 17:50:25.000000000 +0000 @@ -398,7 +398,7 @@ ptok ((UL) resp->ru.ru_ixrss) / MSEC_TO_TICKS (v)); break; case 'M': /* Maximum resident set size. */ - fprintf (fp, "%lu", ptok ((UL) resp->ru.ru_maxrss)); + fprintf (fp, "%lu", (UL) resp->ru.ru_maxrss); break; case 'O': /* Outputs. */ fprintf (fp, "%ld", resp->ru.ru_oublock);

Комментариев нет:

Отправить комментарий