5

I want to use valgrind to analyze my code. The problem is, that I have a huge startup sequence which I'm not interested in.

I found defines in the valgrind/callgrind.h that should help me:

  • CALLGRIND_START_INSTRUMENTATION
  • CALLGRIND_STOP_INSTRUMENTATION
  • CALLGRIND_DUMP_STATS

According to this article I have to execute valgrind with the following options:

valgrind --tool=callgrind --instr-atstart=no ./application

When I do this two files are created:

  • callgrind.out.16060
  • callgrind.out.16060.1

I then want to use kcachegrind to visualize my results. This works great but the makros for the skipping of my startup-sequence seem to do nothing. What do I have to do to measure the performance only in places where I want to?

FrozenTarzan
  • 834
  • 10
  • 30
  • So, to be clear, your issue isn't that the instrumentation is hurting performance, it's just that you don't want data from them. Is that correct? What makes you think the macros aren't doing anything? Are you getting instrumentation data from the startup sequence? – David Schwartz Oct 02 '15 at 10:33
  • Right, I don't want the data to be recorded. Since most of the listed functions show constructors and functions like "init()" or "config" it is hard to find the "run-time relevant parts" of my code. – FrozenTarzan Oct 02 '15 at 10:36
  • And when you start with `--instr-atstart=no` you are seeing data from before you called `CALLGRIND_START_INSTRUMENTATION`? I would make sure you compiled/ran the right code, looked at the right callgrind.out file, and so on. – David Schwartz Oct 02 '15 at 10:37
  • Yes I cleaned and recompiled the whole project. My code looks like this void App::setup() { m_ComplexSystem.config(); CALLGRIND_START_INSTRUMENTATION; m_ComplexSystem.run(); CALLGRIND_STOP_INSTRUMENTATION; CALLGRIND_DUMP_STATSM } – FrozenTarzan Oct 02 '15 at 10:41
  • And you're sure you're not looking at an old `callgrind.out.*` file? – David Schwartz Oct 02 '15 at 10:42
  • 1
    I think you're looking at the wrong `callgrind.out.*` file. Did you try running `kcachegrind` on both of them? – David Schwartz Oct 02 '15 at 10:49
  • You are right! I don't get it though... maybe Qt-Creator did not update something. I deleted the whole folder and rebuilt and now the files contain the correct data – FrozenTarzan Oct 02 '15 at 10:56

2 Answers2

1

Let's assume you have the following open-source program:

int main()
{
    function1();

    function2();
    
    return 0;
}

Let's assume you want to execute Callgrind on only function2().

One approach is to insert Callgrind macros around function2(), and do the recompilation of the program (please compare with the above):

#include <valgrind/callgrind.h>
int main()
{
    function1();

    CALLGRIND_START_INSTRUMENTATION;
    CALLGRIND_TOGGLE_COLLECT;
        function2();
    CALLGRIND_TOGGLE_COLLECT;
    CALLGRIND_STOP_INSTRUMENTATION;

    return 0;
}

In some cases, callgrind.h may not be found, see here for a similar problem. The likely solution is to install/compile valgrind-devel, see this answer.

Finally, you will need to add two new options to your callgrind commands, e.g.:

valgrind --tool=callgrind \
    --collect-atstart=no --instr-atstart=no \ #new options
    <program>

This answer is an extension of this entry.

Herpes Free Engineer
  • 2,425
  • 2
  • 27
  • 34
0

I got it now, but I'm not 100% sure why. I will try to describe my code a bit:

I have an Application class that is responsible for a lot of subsystems. In my original attempt I tried to measure the performance inside the Application like this:

int main(int argc, char *argv[])
{
    Application a(argc, argv);
    return a.exec();
}

void Application::Application(int &argc, char **argv)
{
    m_pComplexSystem = new ComplexSystem();
    m_pComplexSystem->configure();

    CALLGRIND_START_INSTRUMENTATION;
    m_Configurator->start();    
}

Application::~Application()
{
    CALLGRIND_STOP_INSTRUMENTATION;
    CALLGRIND_DUMP_STATS;
    m_pComplexSystem ->stop();

    delete m_pComplexSystem;
    m_pComplexSystem = 0;
}

For some reason the defines were ignored and I got the performance measures of the whole constructor and everything that was done in the configure() call of the ComplexSystem member.

So now I use this code that seems to work:

int main(int argc, char *argv[])
{
    Application a(argc, argv);

    CALLGRIND_START_INSTRUMENTATION;
    int result = a.exec();
    CALLGRIND_STOP_INSTRUMENTATION;
    CALLGRIND_DUMP_STATS;
    return result;
}

Although it is not exactly the same as my original attempt, I can start looking for slow functions now.

FrozenTarzan
  • 834
  • 10
  • 30
  • 1
    Those stupid defines... I have int result = a.exec(); then stop the instrumentation and then return the result... I guess that is the same as just exetic the application, because callgrind stops and dumps automatically... – FrozenTarzan Oct 02 '15 at 11:33