Почему существует разница между потреблением памяти Valgrind-Massif и TOPS?

Я хочу измерить потребление памяти программой в Linux Ubuntu. Я сравнил два инструмента: массив Valgrind и TOP. По некоторым причинам, я получил разные результаты, даже когда использовал "--pages-as-heap=yes", чтобы показать всю память.

  1. Я скомпилировал следующий код:

    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. Какой из них правильный? И почему есть разница?

  1. Хотя веб-сайт 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 ответ

Похоже, вы пытаетесь профилировать отладочные сборки (что совершенно бессмысленно). Потому что в сборках релизов обе эти программы будут иметь только фиктивный основной процесс в качестве компилятора, который отбрасывает все вычисления, поскольку они не имеют побочных эффектов. Также вторая программа вызывает переполнение стека, потому что вы пытаетесь выделить огромные массивы в стеке.

Другие вопросы по тегам