簡體   English   中英

超越堆棧采樣:C ++ Profilers

[英]Beyond Stack Sampling: C++ Profilers

黑客的故事

日期是12/02/10。 聖誕節前幾天正在逐漸消失,作為一名Windows程序員,我幾乎成了一個重要的障礙。 我一直在使用AQTime,我已經嘗試過困,有光澤,而且非常困,正如我們所說,VTune正在安裝。 我曾嘗試使用VS2008探測器,它一直在積極懲罰,而且經常無法察覺。 我使用了隨機暫停技術。 我檢查了呼叫樹。 我已經解雇了函數跟蹤。 但令人痛苦的事實是,我正在使用的應用程序超過一百萬行代碼,可能還有另外一百萬行的第三方應用程序。

我需要更好的工具。 我已經閱讀了其他主題。 我已經嘗試了每個主題中列出的每個分析器。 只需要比這些垃圾和昂貴的選擇更好的東西,或幾乎沒有收獲的荒謬工作。 更復雜的是,我們的代碼經過嚴格的線程化,並運行了許多Qt事件循環,其中一些非常脆弱,以至於由於時序延遲而導致重負荷儀表崩潰。 不要問我為什么我們運行多個事件循環。 沒有人能告訴我。

在Windows環境中,Valgrind還有更多選擇嗎?
有沒有什么比我已經嘗試過的大量破碎工具更好的了?
是否有任何旨在與Qt集成的東西,也許是在隊列中有用的事件顯示?

我嘗試過的工具的完整列表,以及斜體中非常有用的工具:

  • AQTime:相當不錯! 深度遞歸有一些問題,但在這些情況下調用圖是正確的,並且可用於清除您可能遇到的任何混淆。 不是一個完美的工具,但值得嘗試。 它可能適合您的需求,而且在大多數情況下它對我來說當然足夠好。
  • 調試模式下的隨機暫停攻擊:沒有足夠的時間信息。
    一個好工具,但不是一個完整的解決方案
  • Parallel Studios:核選項。 突兀,怪異,瘋狂的強大。 我認為你應該進行30天的評估,並確定它是否合適。 它也很酷。
  • AMD Codeanalyst:精彩,易於使用,非常容易崩潰,但我認為這是一個環境問題。 我建議嘗試一下,因為它是免費的。
  • Luke Stackwalker:在小型項目上工作得很好,它有點試圖讓它在我們的工作上運行。 雖然有一些好的結果,但它絕對取代了我的個人任務Sleepy。
  • PurifyPlus:不支持Win-x64環境,最突出的是Windows 7.否則非常出色。 其他部門的一些同事也發誓。
  • VS2008 Profiler:在功能跟蹤模式下以所需分辨率生成100 + gigs范圍內的輸出。 從好的方面來說,產生可靠的結果。
  • GProf:要求GCC甚至適度有效。
  • VTune:VTune的W7支持犯罪邊界。 否則很棒
  • 密碼:我需要破解自己的工具,所以這是最后的手段。
  • Sleepy \\ VerySleepy:對於較小的應用程序很有用,但在這里讓我失望。
  • EasyProfiler:如果您不介意手動注入一些代碼來指示儀器的位置,那就不錯了。
  • Valgrind:* nix only,但是當你在那個環境中時非常好。
  • OProfile:僅限Linux。
  • Proffy:他們拍野馬。

我沒試過的建議工具:

  • XPerf:
  • Glowcode:
  • Devpartner:

備注:目前英特爾環境。 VS2008,提升庫。 Qt 4+。 他們所有人的悲慘態度:通過trolltech進行Qt / MFC整合。


現在:差不多兩周后,看起來我的問題已經解決了。 感謝各種工具,包括列表中的幾乎所有工具以及我的一些個人技巧,我們發現了主要的瓶頸。 但是,我將繼續測試,探索和嘗試新的分析器以及新技術。 為什么? 因為我欠你們的,因為你們搖滾。 它確實減慢了時間線,但我仍然非常高興繼續嘗試新工具。

概要
在許多其他問題中,最近已將許多組件切換到錯誤的線程模型,由於我們下面的代碼突然不再是多線程的,因此導致嚴重的掛起。 我不能說更多,因為它違反了我的保密協議,但我可以告訴你,通過臨時檢查甚至正常的代碼審查都不會發現這種情況。 如果沒有分析器,調用圖和隨機暫停,我們仍然會在美麗的藍色天空中尖叫着我們的憤怒。 值得慶幸的是,我與一些我見過的最好的黑客合作,我可以獲得一個充滿偉大工具和優秀人才的驚人“詩歌。

Gentlefolk,我非常欣賞這一點,並且唯一的遺憾是我沒有足夠的代表來獎勵你們每個人。 我仍然認為這是一個重要的問題,要比我們到目前為止得到的更好的答案。

結果,在接下來的三個星期的每周,我將提供我能負擔得起的最大獎金,並用我認為不是常識的最好的工具授予它答案。 三個星期后,如果你原諒我的懲罰,我們希望已經積累了一些關於剖析器的確切概況。

帶走
使用分析器。 他們對Ritchie,Kernighan,Bentley和Knuth來說已經足夠了。 我不在乎你認為你是誰。 使用分析器。 如果你得到的那個不起作用,找另一個。 如果你找不到一個,代碼一。 如果你不能編碼一個,或者它是一個小掛機,或者你只是卡住,使用隨機暫停。 如果一切都失敗了,請聘請一些研究生來敲打一個剖析器。


更長遠的觀點
所以,我認為寫一些回顧可能會很好。 我選擇與Parallel Studios廣泛合作,部分原因是它實際上是建立在PIN工具之上的。 在與一些研究人員進行了學術交流之后,我覺得這可能是一些品質的標志。 謝天謝地,我是對的。 雖然GUI有點可怕,但我發現IPS非常有用,盡管我不能輕易地為每個人推薦它。 至關重要的是,沒有明顯的方法可以獲得線級命中數,這是AQT和其他一些分析器提供的,我發現它對於檢查分支選擇率等非常有用。 在網上,我也喜歡使用AQTime,我發現他們的支持非常敏感。 同樣,我必須符合我的建議:他們的很多功能都不能很好地工作,其中一些功能在Win7x64上完全崩潰。 XPerf的表現也令人欽佩,但是對於在某些類型的應用程序上獲得良好讀取所需的采樣細節來說,這種情況非常緩慢。

現在,我不得不說我不認為在W7x64環境中分析C ++代碼有一個明確的選擇,但肯定有一些選項無法執行任何有用的服務。

第一:

時間采樣分析器比CPU采樣分析器更強大。 我對Windows開發工具並不是很熟悉,所以我不知道哪些是哪種。 大多數分析器都是CPU采樣。

CPU采樣分析器每N條指令抓取一次堆棧跟蹤。
此技術將揭示代碼中受CPU限制的部分代碼。 如果這是您應用程序中的瓶頸,那就太棒了。 如果您的應用程序線程花費大部分時間來爭用互斥鎖,那就不那么好了。

時間采樣分析器每N微秒抓取一次堆棧跟蹤。
這種技術將歸零“慢”代碼。 原因是否是CPU綁定,阻止IO綁定,互斥綁定或緩存顛簸部分代碼。 簡而言之,任何一段代碼都會使您的應用程序變得更加突出。

因此,如果可能的話,特別是在分析線程代碼時,請使用時間采樣分析器。

第二:

采樣分析器生成大量數據。 這些數據非常有用,但通常有太多不易使用的數據。 配置文件數據可視化器在這里有很大幫助。 我發現的用於配置文件數據可視化的最佳工具是gprof2dot 不要讓這個名字欺騙你,它會處理各種采樣分析器輸出(AQtime,Sleepy,XPerf等)。 一旦可視化指出違規功能,跳回原始配置文件數據以獲得有關真實原因的更好提示。

gprof2dot工具生成點圖描述 ,然后將其輸入graphviz工具。 輸出基本上是一個調用圖,其功能顏色由它們對應用程序的影響進行編碼。 替代文字

一些提示讓gprof2dot生成好的輸出。

  • 我在圖表上使用了0.001的--skew ,這樣我就可以很容易地看到熱代碼路徑了。 否則int main()支配圖形。
  • 如果您正在使用C ++模板做任何瘋狂的事情,您可能想要添加--strip Boost尤其如此。
  • 我使用OProfile生成我的采樣數據。 為了獲得良好的輸出,我需要將其配置為從我的第三方和系統庫加載調試符號。 一定要做同樣的事情,否則你會發現CRT占你應用程序時間的20%,而實際上正在發生的事情是malloc正在摧毀垃圾堆並且吃掉了15%。

當你嘗試隨機暫停時發生了什么? 我一直在怪物應用程序上使用它。 你說它沒有提供足夠的信息,你建議你需要高分辨率。 有時人們需要一些幫助才能理解如何使用它。

在VS下,我所做的是配置堆棧顯示,因此它不會向我顯示函數參數,因為這會使堆棧顯示完全不可讀,IMO。

然后, 在讓我等待的時候,我會通過點擊“暫停”來拍攝大約10個樣本。 我使用^ A,^ C和^ V將它們復制到記事本中,以供參考。 然后我研究每一個,試圖找出當時試圖完成的過程。

如果它試圖在2個或更多樣本上完成某些事情,並且那個事情並不是絕對必要的話,那么我發現了一個現實問題,而且我大致知道它將節省多少修復。

有些事情你並不真正需要知道,像精確的百分比並不重要,什么那張里面的第三方代碼並不重要,因為你不能做任何事情的那些 你可以做一些事情是一套豐富的代碼調用點,你可以在每個堆棧樣品修改顯示。 那是你快樂的狩獵場。

我發現的事物的例子:

  • 在啟動期間,在嘗試從DLL資源中提取國際化字符串的過程中,它可以是大約30層深。 如果檢查實際的字符串,很容易發現字符串實際上不需要國際化,就像它們是用戶從未真正看到的字符串一樣。

  • 在正常使用期間,某些代碼無意中在某個對象中設置了Modified屬性。 該對象來自一個超類,它捕獲變化並觸發通知,這些通知在整個數據結構中波動,操縱UI,以難以預見的方式創建和消除對象。 這可能會發生很多 - 通知的意外后果。

  • 逐行填寫工作表,逐個單元格。 事實證明,如果您從一組值中一次性構建行,則速度要快得多。

PS如果你是多線程的,當你暫停它時,所有線程都會暫停。 看一下每個線程的調用堆棧。 機會是,其中只有一個是真正的罪魁禍首,其他人都是空轉。

我在AMD CodeAnalyst上取得了一些成功。

你有MFC OnIdle功能嗎? 在過去,我有一個近乎實時的應用程序,我必須修復,當設置為19.2K的速度,PentiumD應該能夠跟上時,丟棄串行數據包。 OnIdle功能就是殺人的東西。 我不確定QT是否有這個概念,但我也會檢查它。

重新啟用VS Profiler - 如果它生成如此大的文件,可能你的采樣間隔太頻繁了? 嘗試降低它,因為你可能還有足夠的樣品。

理想情況下,確保在實際操作問題區域之前不要收集樣本。 所以從收集暫停開始,讓你的程序進行“慢活動”,然后開始收集。 您最多只需要20秒的收集時間。 在此之后停止收集。

這應該有助於減少樣本文件大小,並且只捕獲分析所需的內容。

我已成功使用PurifyPlus for Windows。 雖然它不便宜,但IBM提供的試用版略有癱瘓。 所有你需要用譜進行量化是PDB文件,並用/固定鏈接:NO。 唯一的缺點:不支持Win7 / 64。

Easyprofiler - 我還沒有看到它在這里提到,所以不確定你是否已經看過它。 它在收集度量標准數據方面采用了略微不同的方法。 使用其編譯時配置文件方法的一個缺點是您必須對代碼庫進行更改。 因此,您需要了解緩慢的位置,並在那里插入分析代碼。

按照你的最新評論,聽起來你至少取得了一些進展。 也許這個工具可能會為您提供一些有用的指標。 如果沒有別的東西它有一些真正的圖表和圖片:P

結帳XPerf

這是MS提供的免費,非侵入性和可擴展的分析器。 它是由Microsoft開發的,用於配置Windows。

還有兩個工具建議。

Luke Stackwalker有一個可愛的名字(即使它對我的嘗試有點難度),它不會花費你任何東西,你得到源代碼。 它聲稱也支持多線程程序。 所以它肯定值得一試。

http://lukestackwalker.sourceforge.net/

還有Glowcode,我已經指出我值得使用:

http://www.glowcode.com/

不幸的是我暫時沒有做任何PC工作,所以我沒有嘗試過其中任何一個。 無論如何,我希望這些建議有所幫助。

如果你對事件循環有疑問,可以覆蓋QCoreApplication :: notify()和dosome手動分析(一個或兩個發件人/事件映射到計數/時間)?

我想你首先記錄事件類型的頻率,然后更仔細地檢查這些事件(哪個對象發送它,它包含什么,等等)。 跨線程的信號是隱式排隊的,因此它們最終會出現在事件循環中(顯然也是顯式的排隊連接)。

我們已經完成了在事件處理程序中捕獲和報告異常的情況,所以每個事件都會在那里進行。

只是一個想法。

我使用xperf / ETW來滿足我的所有分析需求。 它有一個陡峭的學習曲線,但非常強大。 如果您在Windows上進行性能分析,那么您必須知道xperf。 我經常使用此分析器在我的代碼和其他人的代碼中查找性能問題。

在我使用它的配置中:

  • xperf從每隔ms執行代碼的每個核心獲取CPU樣本。 采樣率可以增加到8 KHz,樣本包括用戶模式和內核代碼。 這允許找出線程在運行時正在做什么
  • xperf記錄每個上下文切換(允許完美重建每個線程使用的時間),加上線程切換時的調用堆棧,以及為哪個線程准備另一個線程的調用堆棧,允許跟蹤等待鏈並找出線程的原因沒有運行
  • xperf記錄來自所有進程的所有文件I / O.
  • xperf記錄來自所有進程的所有磁盤I / O.
  • xperf記錄哪個窗口處於活動狀態,CPU頻率,CPU電源狀態,UI延遲等。
  • xperf還可以記錄來自一個進程的所有堆分配,來自所有進程的所有虛擬分配等等。

對於所有流程,這是一個時間軸上的大量數據。 Windows上沒有其他分析器可以做到這一點。

我已經在博客上廣泛介紹了如何使用xperf / ETW。 這些博客文章和一些專業品質的培訓視頻可以在這里找到: http//randomascii.wordpress.com/2014/08/19/etw-training-videos-available-now/

如果你想知道如果你不使用xperf會發生什么,請閱讀這些博客文章: http//randomascii.wordpress.com/category/investigative-reporting/這些是我在其他人的代碼中發現的性能問題的故事,這應該是開發人員發現的。 這包括加載到VC ++編譯器中的mshtml.dll,VC ++的find-in-files中的拒絕服務,在數量驚人的客戶機器中的熱量限制,在Visual Studio中緩慢單步執行,在硬件中分配4 GB磁盤驅動程序,powerpoint性能錯誤等等。

編輯:我現在看到你在第一篇文章中提到了這一點。 該死的,我從沒想過我會成為那個人。

您可以使用Pin來更精細地檢測代碼。 我認為Pin會讓你創建一個工具來計算你輸入函數的次數或你在那里花了多少時鍾,大致模仿像VTune或CodeAnalyst這樣的東西。 然后,您可以刪除哪些功能進行檢測,直到您的計時問題消失為止。

我可以告訴你我每天都在使用什么。

a)AMD代碼分析師

  • 它很簡單,它可以讓您快速了解正在發生的事情。 大部分時間都可以。
  • 使用AMD CPU,它會告訴你有關cpu管道的信息,但只有在你有大量循環時才需要它,比如圖形引擎,視頻編解碼器等。

b)VTune。

  • 它在vs2008中得到了很好的集成

  • 在了解熱點之后,您不僅需要對時間進行采樣,還需要對緩存未命中和內存使用等其他內容進行采樣。 非常重要 設置采樣會話,然后編輯屬性。 我總是抽樣時間,內存讀/寫和緩存未命中(三次不同的運行)

但是,除了工具之外,您還需要獲得分析經驗。 這意味着要了解CPU /內存/ PCI的工作原理......所以,這是我的第三個選擇

c)單元測試

如果您正在開發需要巨大性能的大型應用程序,這一點非常重要。 如果您無法在某些部分拆分應用程序,則很難跟蹤CPU使用情況。 我不測試所有的案例和類,但我有硬編碼的執行和具有重要功能的輸入文件。

我的建議是在幾個小測試中使用隨機抽樣,並嘗試標准化配置文件策略。

我剛剛完成了第一個可用的CxxProf版本, 是一個用於C ++的便攜式手動檢測分析庫。

它實現了以下目標:

  • 易於集成
  • 在編譯期間輕松刪除lib
  • 在運行時輕松刪除lib
  • 支持多線程應用程序
  • 支持分布式系統
  • 保持最小的影響力

這些要點是從項目維基中刪除的 ,請查看更多詳細信息。

免責聲明:我是CxxProf的主要開發者

只是拋棄它,即使它不是一個完整的分析器:如果你所追求的只是掛起事件循環,需要長時間處理一個事件, 特殊工具在Qt中是一件簡單的事情。 這種方法可以很容易地擴展,以跟蹤每個事件處理的時間,以及這些事件是什么,等等。 它不是一個通用的分析器,而是一個以事件循環為中心的分析器。

在Qt中,所有跨線程信號槽調用都通過事件循環傳遞,定時器,網絡和串行端口通知以及所有用戶交互也是如此。 因此,觀察事件循環是了解應用程序花費時間的重要一步。

DevPartner最初由NuMega開發,現在由MicroFocus發布,曾經是分析和代碼分析(例如內存和資源泄漏)的首選解決方案。 我最近沒有嘗試過,所以我不能向你保證它會對你有所幫助; 但我曾經用它做過很好的結果,所以這是我考慮在我們的代碼質量過程中重新安裝的替代方案(它們提供了14天的試用期)

雖然你的操作系統是win7,但程序無法在xp下運行? 怎么樣在xp下配置它,結果應該是win7的提示。

這里列出了許多分析器,我自己嘗試了一些 - 但是我最終根據這個來編寫自己的:

http://code.google.com/p/high-performance-cplusplus-profiler/

它當然要求你修改代碼庫,但它非常適合縮小瓶頸,應該適用於所有x86(可能是多核盒子的問題,即它使用rdtsc,但是 - 這純粹是為了指示性時序 - 所以我發現它足以滿足我的需求..)

我使用Orbit profiler,簡單,開源和強大! https://orbitprofiler.com/

暫無
暫無

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

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