DIY Ruby CPU 分析——Part I

【編者按】原文作者 Emil Soman,Rubyist,除此之外竟然同時(shí)也是藝術(shù)家谆级,吉他手,Garden City RubyConf 組織者讼积。本文是DIY Ruby CPU Profiling 的第一部分肥照,由 OneAPM 工程師編譯整理。

alt
alt

在 Codemancers勤众,我們正在建設(shè) Rbkit——一個(gè)針對(duì) Ruby 語(yǔ)言的——擁有新炫酷功能的代碼分析器舆绎。我目前正在實(shí)現(xiàn)一個(gè)嵌在 rbkit gem 里的 CPU 分析器,這將有助 rbkit UI 重建分析 Ruby 進(jìn)程調(diào)用圖们颜,并在屏幕上得出有用的可視化展示吕朵。在這個(gè)過程中,我學(xué)到了許多新東西窥突,很樂意在本系列的博客文章中與您分享努溃。

我們打算一步一步從基礎(chǔ)開始,專門為 Ruby 編寫一個(gè)初級(jí)的 CPU 分析器阻问!在完成時(shí)我們將學(xué)到:

  • 什么是 CPU 分析
  • 分析模式——工具和采樣
  • CPU Time 和 Wall Time ——它們分別是什么意思梧税,如何測(cè)量?
  • 寫一個(gè)簡(jiǎn)單的 C 擴(kuò)展并用于 Ruby 中
  • Ruby Tracepoints——調(diào)用和返回
  • C 語(yǔ)言中的信號(hào)處理
  • 用一個(gè)信號(hào)暫停 Ruby 進(jìn)程并用調(diào)用堆查看
  • 用分析數(shù)據(jù)進(jìn)行一些有用但笨拙的試驗(yàn)

Part I. 介紹 CPU 分析

通過對(duì)你的程序進(jìn)行 CPU 分析称近,可以發(fā)現(xiàn)相較于 CPU 使用率第队,你的程序是多么寶貴。為了分析程序刨秆,你需要使用一個(gè)分析工具并按照下列步驟操作:

  • 開始 CPU 剖析
  • 執(zhí)行你想要分析的代碼
  • 停止 CPU 剖析并得到剖析結(jié)果
  • 分析結(jié)果
  • 通過分析剖析結(jié)果凳谦,你會(huì)發(fā)現(xiàn)使整個(gè)程序緩慢的瓶頸。

分析模式

CPU 剖析可以分為以下兩種方法:

1. 工具

在這種模式下衡未,分析工具利用一些 hooks尸执,由解釋器提供或者插入程序中,來了解調(diào)用圖并測(cè)量在調(diào)用圖中每個(gè)方法的執(zhí)行時(shí)間缓醋。舉個(gè)例子剔交,看一下下面這段 Ruby 代碼:

def main
3.times do
find_many_square_roots
find_many_squares
end
end


def find_many_square_roots
5000.times{|i| Math.sqrt(i)}
end

def find_many_squares
5000.times{|i| i**2 }
end

main

我已經(jīng)插入了一些內(nèi)容,來幫助了解如果 Ruby 解釋器給了我們方法的調(diào)用和返回的 hooks改衩,它們?nèi)绾螆?zhí)行:

def main
# method call hook gets executed
3.times do
find_many_square_roots
find_many_squares
end
# method end hook gets executed
end

def find_many_square_roots
# method call hook gets executed
5000.times{|i| Math.sqrt(i)}
# method end hook gets executed
end

def find_many_squares
# method call hook gets executed
5000.times{|i| i**2 }
# method end hook gets executed
end

main

現(xiàn)在岖常,如果我們能夠打印出當(dāng)前時(shí)間和這些 hooks 內(nèi)部當(dāng)前方法的名稱,會(huì)得到看起來像這種形式的輸出結(jié)果:

sec:00 usec:201007  called      main
sec:00 usec:201108  called      find_many_square_roots
sec:00 usec:692123  returned    find_many_square_roots
sec:00 usec:692178  called      find_many_squares
sec:00 usec:846540  returned    find_many_squares
sec:00 usec:846594  called      find_many_square_roots
sec:01 usec:336166  returned    find_many_square_roots
sec:01 usec:336215  called      find_many_squares
sec:01 usec:484880  returned    find_many_squares
sec:01 usec:484945  called      find_many_square_roots
sec:01 usec:959254  returned    find_many_square_roots
sec:01 usec:959315  called      find_many_squares
sec:02 usec:106474  returned    find_many_squares
sec:02 usec:106526  returned    main

正如你所看到的葫督,此輸出可以告訴我們?cè)诿恳环N方法里面花了多長(zhǎng)時(shí)間竭鞍。同時(shí)也告訴我們板惑,每一個(gè)方法調(diào)用的次數(shù)。這大概就解釋了性能分析工具是如何工作的偎快。

優(yōu)點(diǎn):

高精度
我們得到了方法調(diào)用數(shù)
易于實(shí)施

缺點(diǎn):

每個(gè)被分析的方法執(zhí)行 hooks 時(shí)的額外開銷

2. 采樣

在采樣模式下冯乘,分析器每隔 x 時(shí)間單元打斷一次程序,并查看調(diào)用堆并記錄它的信息(被稱為“樣品”)晒夹。一旦該程序完成運(yùn)行裆馒,分析器收集所有樣品并找出每個(gè)方法出現(xiàn)在所有樣品中的次數(shù)。
很難想象丐怯?讓我們來看看同樣的例子代碼喷好,看看如果我們使用采樣分析器,輸出結(jié)果會(huì)有怎樣的不同读跷。
采樣分析器的輸出結(jié)果如下:

Call stack at 0.5sec: main/find_many_square_roots
Call stack at 1.0sec: main/find_many_square_roots
Call stack at 1.5sec: main/find_many_square_roots
Call stack at 2.0sec: main/find_many_squares

在這個(gè)例子中梗搅,程序每 0.5 秒被中斷一次并且調(diào)用堆棧被記錄。因此效览,通過這個(gè)程序執(zhí)行的過程我們得到了 4 個(gè)樣品无切,find_many_square_roots 記錄于 3 個(gè)樣品中, find_many_squares 只存在于一個(gè)樣品中丐枉。從本次采樣中哆键,我們得到 find_many_square_roots 占用了 75% CPU,與此同時(shí) find_many_squares 只占用了 25% 的 CPU 瘦锹。這就大概解釋了分析器是怎么樣工作的籍嘹。

優(yōu)點(diǎn):

與工具分析相比開銷可忽略不計(jì)
很容易找到緩慢/長(zhǎng)時(shí)間運(yùn)行的方法

缺點(diǎn):

不擅長(zhǎng)測(cè)量短時(shí)間運(yùn)行的方法
我們沒有得到方法調(diào)用數(shù)
很難自己寫出采樣分析器

概括

我們只是調(diào)查了 CPU 分析的含義和兩種常用的 CPU 分析方法。在第 2 部分沼本,我們將探討對(duì)描述 CPU 使用情況的 2 個(gè)單位進(jìn)行測(cè)量—— CPU Time 和 Wall Time噩峦。我們也會(huì)親手寫一些代碼來獲取進(jìn)行測(cè)量锭沟。感謝您的閱讀抽兆!

OneAPM for Ruby 能夠深入到所有 Ruby 應(yīng)用內(nèi)部完成應(yīng)用性能管理和監(jiān)控,包括代碼級(jí)別性能問題的可見性族淮、性能瓶頸的快速識(shí)別與追溯辫红、真實(shí)用戶體驗(yàn)監(jiān)控、服務(wù)器監(jiān)控和端到端的應(yīng)用性能管理祝辣。 想閱讀更多技術(shù)文章贴妻,請(qǐng)?jiān)L問 OneAPM 官方博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蝙斜,一起剝皮案震驚了整個(gè)濱河市名惩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌孕荠,老刑警劉巖娩鹉,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件攻谁,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡弯予,警方通過查閱死者的電腦和手機(jī)戚宦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來锈嫩,“玉大人受楼,你說我怎么就攤上這事『舸纾” “怎么了艳汽?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)等舔。 經(jīng)常有香客問我骚灸,道長(zhǎng),這世上最難降的妖魔是什么慌植? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任甚牲,我火速辦了婚禮,結(jié)果婚禮上蝶柿,老公的妹妹穿的比我還像新娘丈钙。我一直安慰自己,他們只是感情好交汤,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布雏赦。 她就那樣靜靜地躺著,像睡著了一般芙扎。 火紅的嫁衣襯著肌膚如雪星岗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天戒洼,我揣著相機(jī)與錄音俏橘,去河邊找鬼。 笑死圈浇,一個(gè)胖子當(dāng)著我的面吹牛寥掐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播磷蜀,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼召耘,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了褐隆?” 一聲冷哼從身側(cè)響起污它,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后衫贬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蜜宪,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年祥山,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了圃验。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡缝呕,死狀恐怖澳窑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情供常,我是刑警寧澤摊聋,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站栈暇,受9級(jí)特大地震影響麻裁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜源祈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一煎源、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧香缺,春花似錦手销、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至祸轮,卻和暖如春兽埃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背适袜。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工柄错, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人痪蝇。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓鄙陡,卻偏偏與公主長(zhǎng)得像冕房,于是被迫代替她去往敵國(guó)和親躏啰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 【編者按】作者 Emil Soman耙册,Rubyist给僵,除此之外竟然同時(shí)也是藝術(shù)家,吉他手,Garden City ...
    OneAPM閱讀 243評(píng)論 0 1
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理帝际,服務(wù)發(fā)現(xiàn)蔓同,斷路器,智...
    卡卡羅2017閱讀 134,661評(píng)論 18 139
  • 【編者按】作者 Emil Soman蹲诀,Rubyist斑粱,除此之外竟然同時(shí)也是藝術(shù)家,吉他手脯爪,Garden City ...
    OneAPM閱讀 243評(píng)論 0 1
  • 一则北、異同對(duì)比選擇1、Python和ruby的相同點(diǎn): * 都強(qiáng)調(diào)語(yǔ)法簡(jiǎn)單痕慢,都具有更一般的表達(dá)方式尚揣。python是縮...
    沃倫蓋茨閱讀 4,144評(píng)論 2 24
  • 最近一段時(shí)間,學(xué)習(xí)的東西也日益增多掖举,了解的方面也逐漸變廣快骗,對(duì)于以前的一些不懂的東西,也由不懂到懂了塔次,一些由以前模糊...
    Aream閱讀 397評(píng)論 4 3