2014-03-25 28 views
1

我剛開始使用gprof來優化我的慢代碼。我對一個輸出感到困惑,我希望你能幫助我。gprof輸出感到困惑 - 呼叫過多?

這:

   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] 

我運行功能500次,並且對環是尺寸122,所以61000對應於每運行一個執行,122000 2,183000至3,244,000 4,和305000爲5以下是環:

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; 

     } 

    } 

所有條目道理給我,除了一個:的Vector3D(常量的Vector3D &)顯然是被稱爲5倍。但在代碼中無處可用!它的孩子當然會這樣稱呼它,但我認爲他們在gprof列表中有自己的條目。我思考中的缺陷在哪裏?它與Particle []是Vector3Ds的矢量有什麼關係?

對不起,如果這是一個明顯的問題 - 我只是剛開始使用gprof,而且我也是C++的新手。我在網上找不到答案,所以我希望你能幫助我。

非常感謝您的時間!

回答

3

對於類類型Vector3D的對象,這是一個copy constructor。一種情況下,你會隱式地調用一個拷貝構造函數,當你將一個現有的實例作爲參數傳遞給一個函數時。我的猜測是發生在AddToVectorSetPositionSetVelocity的呼叫中,正如我在下面的評論中指出的那樣,共有5個呼叫。爲什麼當你調用SetVelocity的copy constructor不叫你可能會好奇(的Vector3D()),這是最好的解釋,如果你願意知道,通過在這裏讀書的解釋:

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; 
+1

你是絕對正確。事實證明,我忘了做這些函數「const Vector3D&」...猜猜我還是必須習慣這個,來自Java。感謝百萬人發現我的錯誤並迅速回答! – noctilux