Question

I've just started using gprof to optimise my slow code. I am confused by one output, and I hope you can help me out.

Here it is:

                0.01    0.46     500/500         System::Update() [2]
[3]     96.2    0.01    0.46     500         Verlet::Advance() [3]
                0.02    0.19   61000/61122       CalculateAcceleration(std::vector<Particle, std::allocator<Particle> > const&, int) [4]
                0.00    0.06  183000/244127      Vector3D::Vector3D() [8]
                0.00    0.06  305000/676956      Vector3D::Vector3D(Vector3D const&) [6]
                0.00    0.03  122000/122000      Particle::SetPosition(Vector3D const&) [18]
                0.00    0.03  122000/122000      Particle::SetVelocity(Vector3D const&) [19]
                0.02    0.01  183000/183000      Vector3D::LinearCombine(double, Vector3D, double) [23]
                0.00    0.03  549000/921083      Vector3D::~Vector3D() [14]
                0.00    0.00  122000/364484      Vector3D::AddToVector(Vector3D) [30]
                0.00    0.00   61000/182242      std::pow(double, int) [44]
                0.00    0.00   61000/303484      Vector3D::ScalarMultVector(double) [51]
                0.00    0.00   61500/7579826     std::vector<Particle, std::allocator<Particle> >::size() const [25]
                0.00    0.00  366000/366122      std::vector<Particle, std::allocator<Particle> >::operator[](unsigned int) [127]
                0.00    0.00  122000/365606      Particle::GetPosition() const [128]

I am running the function 500 times, and the for loop is of size 122, so 61,000 corresponds to one execution per run, 122,000 to 2, 183,000 to 3, 244,000 to 4, and 305,000 to 5. Here is the loop:

    void Advance() {

        for(int i = 0; i < (int)Particles.size(); i++) {

            const Vector3D& CurrentR_NMinus1 = Particles[i].GetPosition();
            const Vector3D& CurrentR_N = Particles1[i].GetPosition();
            const Vector3D& CurrentA_N = CalculateAcceleration(Particles1,i);

            // Calculate R_N+1

            Vector3D CurrentR_NPlus1;
            CurrentR_NPlus1.AddToVector(CurrentR_N);
            CurrentR_NPlus1.LinearCombine(2, CurrentR_NMinus1, -1);
            CurrentR_NPlus1.LinearCombine(1, CurrentA_N, pow(StepSize,2));

            // Calculate V_N

            Vector3D CurrentV_N;
            CurrentV_N.AddToVector(CurrentR_NPlus1);
            CurrentV_N.LinearCombine(1,CurrentR_NMinus1,-1);
            CurrentV_N.ScalarMultVector(1/(2*StepSize));

            // Update

            Particles[i].SetPosition(CurrentR_N);
            Particles[i].SetVelocity(CurrentV_N);
            t0 += StepSize;

            Particles1[i].SetPosition(CurrentR_NPlus1);
            Particles1[i].SetVelocity(Vector3D());
            t1 += StepSize;

        }

    }

All entries make sense to me, except for one: Vector3D(Vector3D const&) is called 5 times apparently. But it's nowhere in the code! Its children certainly call it, but I thought they had their own entry in the gprof list. Where's the flaw in my thinking? Has it got something to do with Particles[] being a vector of Vector3Ds?

Sorry if this is an obvious question -- I've only just started using gprof, and I'm quite a novice to C++, too. I haven't been able to find answers online however, so I hope you can help me.

Thank you very much for your time!

Was it helpful?

Solution

That is a copy constructor for objects of class type Vector3D. One case where you would implicitly call a copy constructor is when you pass an existing instance by value as argument to a function. My guess is that is happening in the calls to AddToVector and SetPosition and SetVelocity, as I indicated in the comments below, a total of 5 calls. You might be curious why the copy constructor is not called when you invoke SetVelocity(Vector3D()), that is best explained, if you care to know, by reading the explanation here:

Correct usage of rvalue references as parameters

const Vector3D& CurrentR_NMinus1 = Particles[i].GetPosition();
const Vector3D& CurrentR_N = Particles1[i].GetPosition();
const Vector3D& CurrentA_N = CalculateAcceleration(Particles1,i);

// Calculate R_N+1

Vector3D CurrentR_NPlus1;
CurrentR_NPlus1.AddToVector(CurrentR_N);          // copy constructor called
CurrentR_NPlus1.LinearCombine(2, CurrentR_NMinus1, -1);
CurrentR_NPlus1.LinearCombine(1, CurrentA_N, pow(StepSize,2));

// Calculate V_N

Vector3D CurrentV_N;
CurrentV_N.AddToVector(CurrentR_NPlus1);          // copy constructor called
CurrentV_N.LinearCombine(1,CurrentR_NMinus1,-1);  
CurrentV_N.ScalarMultVector(1/(2*StepSize));

// Update

Particles[i].SetPosition(CurrentR_N);             // copy constructor called
Particles[i].SetVelocity(CurrentV_N);             // copy constructor called
t0 += StepSize;

Particles1[i].SetPosition(CurrentR_NPlus1);       // copy constructor called
Particles1[i].SetVelocity(Vector3D());
t1 += StepSize;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top