Reputation: 803
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!
Upvotes: 1
Views: 305
Reputation: 11582
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;
Upvotes: 3