Go 程式的效能調試問題 - CPU 篇

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

註:本文的原文 Debugging performance issues in Go programs 由 Dmitry Vyukov 在 05/10/2014 - 07:06 編寫
註:原文太長,大家要看全部的請看原文,其他的部分,後續慢慢翻譯。

讓我們假設你想提升你的GO程式的效能。這裡有一些工具可以協助你完成這個任務。這些工具能協助你定位多種類型的熱點(CPU,IO,記憶體),你為了能夠顯著提升程式效能,你必須專註於熱點發生的地方。儘管如此,另外一個結果是可能的--這些工具能協助你確定程式中明顯的效能缺陷。例如,當你在每個程式啟動的時候,你可以在每次查詢的之前準備一個 SQL 陳述式。另外一個例子是如果一個 O(N^2) 演算法在某種程度上陷入了一個明顯存在並且期望的 O(N) 情況。為了確定這樣的情況,你需要完整性的檢查你在 profiles 中看到的。例如第一種情況下大量的時間花費在 SQL 陳述式的準備上,這已經超越了警示線了。

同樣重要的是要理解效能影響的各種邊界因素。例如,一個程式通過 100 Mbps 的頻寬串連通訊,並且它已經使用超過 90 Mbps,這裡就沒有什麼可以對這程式做的來提升它的效能了。這些類似的邊界因素包括 磁碟 IO,記憶體消耗和計算任務。

考慮到這一點,我們可以查看這些可用的工具。

注意:這些工具可能相互幹擾,例如,精確的記憶體分析可能影響CPU分析。goroutine 阻塞分析可能影響調度追蹤等等,隔離地使用這些工具以便得到更加精確的資訊。

注意:這裡所有的描述都是基於 Go1.3 版本的

CPU 分析器

Go runtime 包含了內建的 CPU 分析器,這顯示了函數消耗的 CPU 時間百分比,這裡你有3種方式訪問它:

  1. 最簡單的一個方式是使用 go test 命令的 -cpuprofile 標記。例如,如下命令:
    $ go test -run=none -bench=ClientServerParallel4 -cpuprofile=cprof net/http
    將配置給出的基準和 CPU 的概要分析寫入 cprof 檔案。
    然後:
    $ go tool pprof --text http.test cprof
    將列印一份熱點函數列表。
    這有幾個可用的輸出類型,最有用的幾個為: --text,--web 和 --list 。運行 go tool pprof 來得到最完整的列表。
    這個選項最明顯的特點就是它只適用於測試。
  2. net/http/pprof 包。這是網路服務的理想解決方案。你僅僅只需要 import net/http/pprof 並且用如下命令收集概要檔案:
$ go tool pprof --text mybin http://myserver:6060:/debug/pprof/profile
  1. 手工配置收集。你需要 import runtime/pprof 並且 把如下代碼加入 main 函數中:
if *flagCpuprofile != "" {    f, err := os.Create(*flagCpuprofile)    if err != nil {        log.Fatal(err)    }    pprof.StartCPUProfile(f)    defer pprof.StopCPUProfile()}

這份概要檔案會被寫入指定的檔案中,想象它和第一個選項一樣的命令列方式。

這裡是一個使用 --web 選項產生的直觀的概要檔案樣本:

你可以使用 -list=funcname 選項來研究單個函數,下面的 概要檔案顯示了在 append 函數中所花費的時間:

.      .   93: func (bp *buffer) WriteRune(r rune) error {.      .   94:     if r < utf8.RuneSelf {5      5   95:         *bp = append(*bp, byte(r)).      .   96:         return nil.      .   97:     }.      .   98: .      .   99:     b := *bp.      .  100:     n := len(b).      .  101:     for n+utf8.UTFMax > cap(b) {.      .  102:         b = append(b, 0).      .  103:     }.      .  104:     w := utf8.EncodeRune(b[n:n+utf8.UTFMax], r).      .  105:     *bp = b[:n+w].      .  106:     return nil.      .  107: }

你可以在這裡找到 pprof 工具的詳細資料和描述的數字圖。

當它不能解鎖堆棧的時候,這裡有關於分析器使用的3條特別條目:GC, System and ExternalCode。GC 表示記憶體記憶體回收的時間花費,見下面的記憶體分析器和垃圾收集器跟蹤最佳化建議部分。System 表示 goroutine 調度花費的時間,堆棧管理代碼以及其他輔助的 runtime 代碼。ExternalCode 表示本地動態庫花費的時間。

這裡有些提示關於如何解釋說明你在 profile 中看到的資訊。

如果很多時間花費在 runtime.mallocgc 函數,程式可能在小記憶體配置上面花費過多。 profile 會告訴你分配從哪裡來,看記憶體分析器建議如何最佳化的部分。

如果很多時間花費在 channel 操作部分,sync.Mutex 代碼和其他 synchronization primitives或者是系統組件,程式可能在承受資源競爭。考慮重構程式,以消除對共用資源的頻繁訪問。常見的技術包括分區、分區,本地緩衝/批量處理和寫時拷貝技術。

如果很多時間花費在 syscall.Read/Write 上面,程式可能在小讀寫上面花費代價太大。Bufio 封裝 os.File 或是 net.Conn 能對這種情況有協助。

如果很多時間花費在 GC 組件上面,程式不是分配了太多的臨時對象就是 heap size 設定過小導致記憶體回收頻繁發生。請看垃圾收集器跟蹤和記憶體分析器最佳化建議部分。

注意: CPU profiler 目前不能在 darwin 上工作
注意: 在 windows 伺服器上你需要安裝 Cygwin, Perl and Graphviz 來產生 svg/web 格式的概要檔案
注意: 在 Linux 上你可以嘗試 perf system profiler,它不能解鎖 GO 的堆棧,但是它能分析並且解鎖 cgo/SWIG 代碼和核心。所以它在定位分析本地/核心效能瓶頸上非常有用。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.