簡體   English   中英

C++ 分析(谷歌 cpu perf 工具)究竟測量了什么?

[英]What exactly does C++ profiling (google cpu perf tools) measure?

我試圖開始使用 Google Perf Tools 來分析一些 CPU 密集型應用程序。 這是一種統計計算,使用“ofstream”將每個步驟轉儲到一個文件中。 我不是 C++ 專家,所以我很難找到瓶頸。 我的第一遍給出了結果:

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”(我在哪里可以找到它?)似乎來自寫入 output 文件。 現在,讓我感到困惑的是,如果我注釋掉所有outfile << "text"語句並運行 pprof,95% 在SliceStep::DoStep並且 `_write$UNIX2003' 消失了。 但是,按照總時間衡量,我的應用程序沒有加速。 整個事情的速度不到 1%。

我錯過了什么?

添加:沒有outfile <<語句的 pprof output 是:

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::timer 計時,從分析器開始的地方開始,到它結束的地方結束。 我不使用線程或任何花哨的東西。

從我的評論:

你從分析器中得到的數字表明,如果沒有打印語句,程序應該快 40% 左右。

然而,運行時間幾乎保持不變。

顯然其中一個測量值一定是錯誤的。 這意味着您必須進行更多更好的測量。

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

如果結果仍然不是決定性的,你需要一個更好的測試用例:

  • 使用更大的問題
  • 測量前做熱身。 做一些循環,然后開始任何測量(在同一過程中)。

Tiristan:一切都在用戶身上。 我想我正在做的事情非常簡單......文件一直處於打開狀態這一事實意味着什么嗎?

這意味着探查器是錯誤的。

使用 python 向控制台打印 100000 行結果類似於:

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

我的觀點是:你的內部測量時間表明你沒有從禁用 output 中獲得任何好處。Google Perf Tools 說你應該這樣做。 誰錯了?

_write$UNIX2003 可能指的是write POSIX 系統調用,它輸出到終端。 I/O 與幾乎任何其他東西相比都非常慢,因此如果您正在編寫相當多的 output,那么您的程序在那里花費大量時間是有道理的。

我不確定為什么當您刪除 output 時您的程序不會加速,但我無法僅根據您提供的信息進行猜測。 很高興看到一些代碼,甚至是刪除 cout 語句時的 perftools output。

Google perftools 收集調用堆棧的樣本,因此您需要了解這些樣本。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM