2009-06-16 25 views
8

我試圖開始使用Google Perf Tools來分析一些CPU密集型應用程序。這是一個統計計算,使用`ofstream'將每個步驟轉儲到一個文件。我不是C++專家,所以我很難找到瓶頸。我第一遍給出的結果:C++分析(谷歌CPU處理工具)究竟是什麼措施?

 
Total: 857 samples 
    357 41.7% 41.7%  357 41.7% _write$UNIX2003 
    134 15.6% 57.3%  134 15.6% _exp$fenv_access_off 
    109 12.7% 70.0%  276 32.2% scythe::dnorm 
    103 12.0% 82.0%  103 12.0% _log$fenv_access_off 
     58 6.8% 88.8%  58 6.8% scythe::const_matrix_forward_iterator::operator* 
     37 4.3% 93.1%  37 4.3% scythe::matrix_forward_iterator::operator* 
     15 1.8% 94.9%  47 5.5% std::transform 
     13 1.5% 96.4%  486 56.7% SliceStep::DoStep 
     10 1.2% 97.5%  10 1.2% 0x0002726c 
     5 0.6% 98.1%  5 0.6% 0x000271c7 
     5 0.6% 98.7%  5 0.6% _write$NOCANCEL$UNIX2003 

這是令人驚訝的,因爲發生在SliceStep所有真正的計算:: DoStep。 「_write $ UNIX2003」(我在哪裏可以找出它是什麼?)似乎來自編寫輸出文件。現在,讓我困惑的是,如果我將所有outfile << "text"語句註釋掉並運行pprof,則95%位於SliceStep::DoStep,並且`_write $ UNIX2003'消失。然而,我的應用程序沒有加速,以總時間來衡量。整件事速度不到1%。

我錯過了什麼?

補充: 沒有outfile <<語句pprof輸出是:

 
Total: 790 samples 
    205 25.9% 25.9%  205 25.9% _exp$fenv_access_off 
    170 21.5% 47.5%  170 21.5% _log$fenv_access_off 
    162 20.5% 68.0%  437 55.3% scythe::dnorm 
     83 10.5% 78.5%  83 10.5% scythe::const_matrix_forward_iterator::operator* 
     70 8.9% 87.3%  70 8.9% scythe::matrix_forward_iterator::operator* 
     28 3.5% 90.9%  78 9.9% std::transform 
     26 3.3% 94.2%  26 3.3% 0x00027262 
     12 1.5% 95.7%  12 1.5% _write$NOCANCEL$UNIX2003 
     11 1.4% 97.1%  764 96.7% SliceStep::DoStep 
     9 1.1% 98.2%  9 1.1% 0x00027253 
     6 0.8% 99.0%  6 0.8% 0x000274a6 

這看起來像我期望的是什麼,但我看到的性能沒有明顯的增加(在10秒的計算即0.1秒) 。該代碼基本上是:

ofstream outfile("out.txt"); 
for loop: 
    SliceStep::DoStep() 
    outfile << 'result' 
outfile.close() 

更新:我定時使用boost ::計時器,開始在那裏探查開始和結束的地方結束。我不使用線程或任何幻想。

+0

你如何測量運行時間? 爲這兩種配置做一次「time ./yourprogramm」。 你使用多線程嗎? – ebo 2009-06-16 19:25:34

+0

用時間運行並測量sys/usr時間。分析器數字表明,如果沒有輸出,您的運行時間應該減少40%。最簡單的解釋是分析器測量是偏斜的。 – ebo 2009-06-16 19:42:20

回答

3

從我的意見:

您從探查得到說的數字,程序應該是沒有報表的打印速度在40%左右。

但是,運行時保持幾乎相同。

顯然其中一個測量結果必須是錯誤的。這意味着你必須做更多更好的測量。

首先我建議從另一個簡單的工具開始:時間命令。這應該讓你大致瞭解你的時間花在哪裏。

如果結果仍然沒有定論,你需要一個更好的測試用例:

  • 使用一個更大的問題
  • 測量前做熱身。做一些循環並在之後開始任何測量(在相同的過程中)。

Tiristan:這一切都在用戶。我所做的很簡單,我認爲...文件全部打開的事實是否意味着什麼?

這意味着分析器是錯誤的。

打印10萬株,以使用python的結果類似控制檯:

for i in xrange(100000): 
    print i 

爲了安慰:

time python print.py 
[...] 
real 0m2.370s 
user 0m0.156s 
sys  0m0.232s 

對戰:

time python test.py > /dev/null 

real 0m0.133s 
user 0m0.116s 
sys  0m0.008s 

我的觀點是: 你的內在測量ents 時間顯示你不會從禁用輸出中獲得任何收益。谷歌Perf工具說,你應該。誰錯了?

1

_write $ UNIX2003可能是指輸出到終端的write POSIX系統調用。與幾乎其他任何東西相比,I/O非常緩慢,所以如果您正在編寫一些合理的輸出,那麼您的程序在這裏花費大量時間是有道理的。

我不確定爲什麼你的程序不會在你刪除輸出時加快速度,但我不能僅僅猜測你提供的信息。在刪除cout語句時,很高興看到一些代碼,甚至是perftools輸出。

1

Google perftools收集調用堆棧的樣本,因此您需要的是獲得對這些樣本的一些可見性。

根據文檔,您可以顯示語句或地址粒度的調用圖。這應該告訴你你需要知道什麼。