使用 WITCH 來觀察系統(tǒng)的無效處理

最近看了一篇 Paper - Watching for Software Inefficiencies with Witch媚送,覺得作者排查性能問題的思路很不錯匾旭,這里記錄一下。

什么是無效處理

對于性能調(diào)優(yōu)來說尽棕,我們會關(guān)注很多指標(biāo)答憔,這里味赃,WITCH 主要關(guān)注的是系統(tǒng)的 infficiencies,也就是無效的處理虐拓。通常的無效處理可能包括:

  • 計算了一個不會被使用的結(jié)果
  • 重復(fù)計算了某一個結(jié)果
  • 無效的數(shù)據(jù)移動
  • 過分的同步

大家都知道心俗,無效處理會對系統(tǒng)性能造成影響,我們需要盡量避免蓉驹。雖然現(xiàn)在編譯器在很多時候都能對代碼做很多優(yōu)化城榛,但僅僅靠編譯器是不夠的,我們還需要其他的方法來檢查發(fā)現(xiàn)系統(tǒng)無效處理的地方态兴。

WITCH 的設(shè)計與實現(xiàn)

要排查系統(tǒng)性能問題狠持,對我來說,最先想到的就是使用 perf 這類型的工具瞻润,但無論是 perf 還是 vtune喘垂,它們都是基于采樣的,是一種 Coarse-grained profiler绍撞,雖然對系統(tǒng)影響較小正勒,但并不精確,在一些情況下面其實并不能很好的發(fā)現(xiàn)無效處理傻铣。

另一種就是 Fine-grained profiler章贞,譬如 DeadSpy,它們會詳細(xì)的分析動態(tài)指令非洲,從而發(fā)現(xiàn)無效處理阱驾,但也會給系統(tǒng)造成非常大的負(fù)擔(dān)就谜,是的系統(tǒng)性能下降。

而對于 WITCH 來說里覆,它融合了 Coarse-grained 和 Find-grained,核心想法就是先用 PUMs 對系統(tǒng)進(jìn)行采樣缆瓣,然后使用 hardware debug registers 來給采樣的地址加上斷點喧枷,當(dāng)后續(xù)系統(tǒng)訪問到這些地址的時候,觸發(fā)對應(yīng)的判斷程序弓坞,看是否是無效處理隧甚。

WITCH 的原理非常簡單,但要做好渡冻,其實還需要處理很多問題戚扳。在繼續(xù)開始之前,我們可以先簡單介紹一下系統(tǒng)調(diào)優(yōu)里面一些背景知識族吻。

常用術(shù)語

  • Hardware Performance Monitoring Units

    也就是通常說的 PMU∶苯瑁現(xiàn)代的 CPU 都會提供很多硬件事件的計數(shù)器,譬如 loads超歌,stores砍艾,CPU cycles 等。當(dāng)計數(shù)器的值超過了一個閾值之后巍举,PMU 就會觸發(fā)一個溢出中斷脆荷,這個中斷就會被 profiler(譬如 perf)給捕捉到并且處理。

  • Hardware Debug Registers

    Hardware debug registers 其實就可以認(rèn)為是我們在用 gdb 調(diào)試的時候設(shè)置的斷點懊悯。當(dāng)程序的 Program counter (PC) 運行到某一個地址或者是一條指令訪問到了一個特定的地址蜓谋,hardware debug registers 就會捕獲 CPU 的執(zhí)行。在現(xiàn)代的 x86 架構(gòu)中炭分,通常有 4 個 debug registers桃焕。

  • Linux Perf events_

    Linux 提供了一套標(biāo)準(zhǔn)的接口用來對 PMU 進(jìn)行采用和編程,主要使用的是 perf_event_open 和相關(guān)的 ioctl 調(diào)用欠窒。當(dāng) PMU 的事件溢出之后覆旭,Linux 內(nèi)核會給相關(guān)的線程發(fā)送信號,并且將取樣的 PMU 數(shù)據(jù)追加到一個循環(huán) buffer 里面岖妄。

  • Call Path Profiling

    當(dāng)對應(yīng)事件觸發(fā)的時候型将,我們能通過 Call path profiling 拿到當(dāng)前的 calling context,也就是整個事件的調(diào)用鏈荐虐。一個 calling context 從入口函數(shù)(譬如 main 或者線程開始函數(shù))的 instruction pointer (IP) 開始七兜,然后到觸發(fā)這個事件的指令這里結(jié)束。

  • Watchpoint

    Watchpoint 就是類似于 gdb 里面的斷點設(shè)置福扬。我們可以設(shè)置 write W_TRAP 以及 read-or-write RW_TRAP腕铸。

例子

這里我們用 WITCH 的 DeadCraft 來說明下 WITCH 是如何工作的惜犀,DeadCraft 主要是用來檢查 dead store。所謂 dead store狠裹,就是當(dāng)我們給一個地址設(shè)置了一個值扁远,然后馬上又用一個新的值在同樣的地址設(shè)置了,那么這個就是 dead store泻轰。如果我們設(shè)置了一個值疙渣,但后面馬上就 load 讀取了,這個就不是 dead store俗冻。

上面是 WITCH 用來檢查 dead store 的流程:

  1. PMU store event 的計數(shù)器溢出礁叔,觸發(fā)中斷
  2. WITCH 捕獲到了信號,得到 calling context C-watch 以及地址 M迄薄,跟 AccessType 合成一個 tuple <C-watch, M, AccessType> 發(fā)送給 DeadCraft
  3. DeadCraft 讓 WITCH 去監(jiān)控后續(xù)對地址 M 的 load 或者 store
  4. WITCH 給設(shè)置一個 RW_TRAP 的 watchpoint
  5. 后續(xù)程序訪問到 M琅关,watchpoint 捕獲
  6. WITCH 處理,得到 calling context C-trap讥蔽,并且將 <C-trap, M, AccessType> 給 DeadCraft
  7. 如果 AccessType 是 store涣易,那么 DeadCraft 就認(rèn)為這個是一個 dead store,并且將這次 dead store 設(shè)置為 <C-watch, C-trap>

實現(xiàn)

上面說到了 WITCH 一個簡單的例子勤篮,這里說下 WITCH 是如何實現(xiàn)的都毒, WITCH 主要是基于 HPCToolkit,主要有:

  • PMU Sampling : 在 Intel CPU 上碰缔,主要設(shè)置 MEM_UOPS_RETIRED:ALL_STORESMEM_UOPS_RETIRED:ALL_LOADS Registration
  • Watchpoint : WITCH 會自動確定機(jī)器上面的 hardware debug registers账劲,使用 Linux perf_event 接口去注冊一個 watchpoint 事件 HW_BREAKPOINT。WITCH 會注冊一個 signal handler 去捕獲 watchpoint 拋出的異常金抡。WITCH 也會把采樣周期設(shè)置為 1 瀑焦,用來保證只要訪問到了監(jiān)控的內(nèi)存就會跑出異常,被 WITCH 捕獲梗肝。
  • Precise PC : 當(dāng) watchpoint 觸發(fā)的時候榛瓮,其實在 signal handler 里面得到的 PC(Context PC) 并不是當(dāng)前觸發(fā)中斷的 PC (Precise PC),而是在 Precise PC 之前的一條指令巫击。WITCH 使用 Last Branch Record (LBR)來得到 precise PC禀晓。
  • Fast Watchpoint Replacement : WITCH 需要經(jīng)常的關(guān)閉 watchpoint,并且關(guān)掉所有跟這些 watchpoint 相關(guān)的內(nèi)核資源坝锰,WITCH 給 perf_event ioctl 接口加了個 PERF_EVENT_IOC_MODIFY_ATTRIBUTES粹懒。
  • Stack Addresses : WITCH 會用 sigaltstack 機(jī)制來用一個額外的 signal stack 處理 PMU 以及 watchpoint 的 signal。

挑戰(zhàn)

上面整個流程看起來是很簡單顷级,但實際還是有很多困難需要克服的凫乖,最大的困難就是采樣其實并不是精確的。譬如如下的例子:

1: for (int i = 1; i <= 100K; i++) {
2:  arrya[i] = 0;
3: }
4: for (int j = 1; j <= 100K; j++) {
5:  arrya[j] = j;
6: }

假設(shè)采樣周期是 10K,我們就只有一個 hardware debug register帽芽,那么 WITCH 會在第一個 array[10K] 的時候設(shè)置一個 watchpoint删掀,然后在 array[20K] 會有第二次采樣,但這時候已經(jīng)沒有空間設(shè)置 watchpoint 了导街。

如果采用最通常的做法披泪,后面的替換掉最老的,這個是不能工作的搬瑰。譬如當(dāng)我們在第一個循環(huán)最后 array[100K] 設(shè)置了 watchpoint 之后付呕,下一個在第二個循環(huán) array[10K] 會覆蓋掉之前的,但這時候其實是沒法發(fā)現(xiàn) dead store 的跌捆。為了解決這個問題,WITCH 引入概率機(jī)制來決定對于某一次采樣象颖,是否需要設(shè)置 watchpoint佩厚。

假設(shè)系統(tǒng)有 N 個 debug register,對于第 k 次采樣说订,k > N抄瓦,按照 N / k 的概率替換掉 N 里面的一個 watchpoint。也就是說陶冷,任何采樣都有 N / k 的概率來被監(jiān)控到钙姊。只要 watchpoint 被處罰,概率就被重置為 1埂伦。具體的推導(dǎo)可以詳細(xì)參考 paper煞额。當(dāng)然,paper 里面還說了其他很多的困難沾谜,這里就不一一說明了膊毁。

小結(jié)

總的來說,WITCH 的思路還是挺不錯的基跑,Paper 作者也通過它來找到了一些軟件中的無效處理婚温。我也在 Github 上面找到了 WITCH ,本來想試試媳否,看能不能找找 TiKV 中的無效處理栅螟,但一看安裝說明,需要裝一個定制版本的 Linux篱竭,就只好先打消了這個念頭力图,后面在嘗試吧。如果你對這塊很感興趣室抽,想在 TiKV 里面試試搪哪,歡迎聯(lián)系我 tl@pingcap.com

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市晓折,隨后出現(xiàn)的幾起案子惑朦,更是在濱河造成了極大的恐慌,老刑警劉巖漓概,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件漾月,死亡現(xiàn)場離奇詭異,居然都是意外死亡胃珍,警方通過查閱死者的電腦和手機(jī)梁肿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來觅彰,“玉大人吩蔑,你說我怎么就攤上這事√钐В” “怎么了烛芬?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長飒责。 經(jīng)常有香客問我赘娄,道長,這世上最難降的妖魔是什么宏蛉? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任遣臼,我火速辦了婚禮,結(jié)果婚禮上拾并,老公的妹妹穿的比我還像新娘揍堰。我一直安慰自己,他們只是感情好辟灰,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布个榕。 她就那樣靜靜地躺著,像睡著了一般芥喇。 火紅的嫁衣襯著肌膚如雪西采。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天继控,我揣著相機(jī)與錄音械馆,去河邊找鬼。 笑死武通,一個胖子當(dāng)著我的面吹牛霹崎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播冶忱,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼尾菇,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起派诬,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤劳淆,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后默赂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沛鸵,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年缆八,在試婚紗的時候發(fā)現(xiàn)自己被綠了曲掰。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡奈辰,死狀恐怖栏妖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情奖恰,我是刑警寧澤底哥,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站房官,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏续滋。R本人自食惡果不足惜翰守,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望疲酌。 院中可真熱鬧蜡峰,春花似錦、人聲如沸朗恳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽粥诫。三九已至油航,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間怀浆,已是汗流浹背谊囚。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留执赡,地道東北人镰踏。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像沙合,于是被迫代替她去往敵國和親奠伪。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)绊率,斷路器谨敛,智...
    卡卡羅2017閱讀 134,659評論 18 139
  • 轉(zhuǎn)自:http://blog.csdn.net/highning0007/article/details/3799...
    某人在閱讀 1,674評論 0 0
  • 我在北京佣盒,北京這幾天雖然陽光好到爆,但是氣溫卻還是凍成狗顽聂。愛美的人早早的露出了腳踝肥惭,也許是自己真的老了,居然到了不...
    青木_21閱讀 201評論 0 0
  • 文 Ⅰ 77若初 (一) 有人說七年就是一輩子紊搪,人生會經(jīng)歷許多輩子蜜葱。這話我是很認(rèn)同的,許多從前的人和事每每想起耀石,總...
    若初的清明覺知閱讀 1,661評論 10 13