Почему существует разница между потреблением памяти Valgrind-Massif и TOPS?
Я хочу измерить потребление памяти программой в Linux Ubuntu. Я сравнил два инструмента: массив Valgrind и TOP. По некоторым причинам, я получил разные результаты, даже когда использовал "--pages-as-heap=yes", чтобы показать всю память.
Я скомпилировал следующий код:
void delay(double secs) { int i,j; for(j=0;j<5000*secs;j++) for(i=0;i<99999;i++); } int main() { delay(30); return 0; }
Команда TOP показала потребление 4200 КБ виртуальной памяти, когда программа находилась в функции задержки. Инструмент Valgrind-Massif дал расход 6340608B. Какой из них правильный? И почему есть разница?
Хотя веб-сайт Massif сообщает, что с включенной опцией --pages-as-heap = yes стек также измеряется, я не добился успеха с этим. Например, для следующей программы:
#include <stdlib.h> void delay(double secs) { int i,j; for(j=0;j<5000*secs;j++) for(i=0;i<99999;i++); } void func(int n) { char x[2000000]; int i; if(n==0) return; for(i=0;i<2000000;i++) x[i]=(char)n; delay(15); // Delay number 2,3,4,5 func(n-1); return; } int main() { delay(30); // Delay number 1 func(4); delay(30); // Delay number 6 return 0;}
По данным TOP, потребление памяти составило: 4200 КБ, затем 6032 КБ, затем 7984 КБ, затем 9936 КБ, затем 11892 КБ, а затем 13844 КБ. Тем не менее, Massif сообщил о 6336512 B в начале программы (на самом деле, были некоторые колебания в памяти, но они остановились очень быстро, и они были не очень большими). Кажется, что по какой-то причине Massif не измеряет стек при этой настройке. Почему это происходит?
Редактировать:
Я пытался скомпилировать в режиме релиза, но получил те же проблемы. Я скомпилировал следующий код:
#include<stdio.h>
#include <stdlib.h>
unsigned long delay(double secs)
{ long i,j,k,counter=0;
for(k=0;k<160000;k++)
for(j=0;j<5000*secs;j++)
for(i=0;i<99999;i++)
counter++;
return counter;
}
int main()
{
unsigned long i;
i=delay(10);
printf("%lu\n",i);
return 0;
}
и все еще получил 4200 КБ с ТОПом и около 6 МБ с массивом. Я скомпилировал код с помощью следующей команды:
g++ -O2 -Wall myprog.c -o myprog
Кроме того, когда я запустил программу, я увеличил размер стека с помощью: ulimit -s 2000000000 и также увеличил размер стека при запуске программы с Massif, так что я не получу переполнение стека. И я все еще получаю те же результаты.
1 ответ
Похоже, вы пытаетесь профилировать отладочные сборки (что совершенно бессмысленно). Потому что в сборках релизов обе эти программы будут иметь только фиктивный основной процесс в качестве компилятора, который отбрасывает все вычисления, поскольку они не имеют побочных эффектов. Также вторая программа вызывает переполнение стека, потому что вы пытаетесь выделить огромные массивы в стеке.