2016年12月28日 星期三

書摘:Effective Debugging - Item 17 放大程式跑失敗的後果



Item 17: Increase the Prominence of a Failure's Effects


  • 使用版本控制來增加放大失敗效應的程式碼以便回溯,這樣才不會誤把測試程式放進 production code
  • 放大手段一:移除可能的程式碼片段。例如使用一個永遠成立的 if 條件式(ex. if(0))去執行有嫌疑的程式碼片段。
  • 放大手段二:修改程式碼,讓原本的輸出資料變得很容易觀察。例如把輸出資料故意變成原本的一千倍。
  • 放大手段三:壓力測試、並且使得失敗很快速地可以複製出來。例如使用 Apache JMeter 來執行對網站的 DDoS。故意指定超過的 thread number 來測試 concurrency。故意讓程式跑在資源缺乏的地方,例如寫入故意寫在小容量的 USB 磁碟裡。
  • 放大手段四:fuzzying。例如使用 zzuf 來亂數產生測試用的輸入資料。

書摘:Effective Debugging

最近在讀 Effective Debugging[1],發現編排方式非常適合早餐的時候閱讀 XD 作者將自身的經驗歸納成 66 個條目,每個條目長短剛好是一個早餐的閱讀份量。遣詞造句也算潛白,即使像我這種非英語母語人士也可以感受到閱讀樂趣。

當初進了 Canonical 公司[2]工作之後,基於之前大多經驗是開發 web 或是寫寫 script 跑科學計算 job,往往有完整的、成熟的 IDE 可以使用,因此有一小段時間對於除錯環境不一定well-prepared 的系統程式除錯感到不太適應。這三年摸索過去後,偶然間看到這本書,覺得很是幫自己過去三年在公司中遇到的問題做了很好的回顧和整理,當然也有啟發;因此一讀就欲罷不能 XD

接下來打算在每次閱讀之後,開始摘要 66 個條目中的內容與自己的心得。敬請期待。


Item 17 放大程式跑失敗的後果


[1] Effective Debugging: 66 Specific Ways to Debug Software and Systems (Effective Software Development Series) 1st Edition by Diomidis Spinellis,我讀的是 Amazon 上面的 Kindle 版本。
[2] https://zh.wikipedia.org/zh-tw/Canonical%E5%85%AC%E5%8F%B8

2016年12月22日 星期四

初探 PRIME 技術


最近收到通知說 12.0.5 的 mesa 打算 backport 回 Ubuntu 16.04,並且取代原本 16.04 中11.2.0 版本的 mesa,希望在正式釋出 backport 版本前提供更多測試。因此對這個技術稍微了解了一下,摘要如下。

詞彙

provider:
提供運算資源的單位,例如一張獨立顯卡。

sink output:
在這裡指有連接外部裝置 port 的 provider,但基本上不太負擔運算繪圖,只輸出。不要跟電路學中的 sink-source 混淆(電路學中是指裝置接地和電壓方式的不同)

source output:
在這裡是指負擔運算繪圖,但輸出由其他 provider.

multiplexer:
較早期不是採用動態切換時,需要關掉一個 GPU 再去啟動另外一個 GPU來達成切換,負責開關的裝置叫做 multiplexer[a],通常是一種硬體。比較新的裝置是不需要(硬體上的) multiplexer,稱為 muxless。附註資料[c][d]中的硬體透過 GCN (一種新的指令集架構)支援這種功能。


因此在處理這類問題,我們會需要知道(下文有對應指令):

  • provider 的資訊,包括他是 sink or source output
  • render 時的資訊;例如是誰在負責運算、運算結果的表現如何。

我們會需要執行下面這些動作(下文有對應指令):

  • 指定誰當 sink、誰當 source


使用情境

案例一:PRIME


一個支援 muxless 的系統有兩個顯卡,分別是主要的 integrated graphic 和第二顯卡。輸出 port 在 integrated graphic 上面。

因為 integrated graphic 是常駐的、低耗電的晶片裝置,所以平常的運算都交給他。有時如果要把運算負擔(loading)從 integrated graphic 交給第二顯卡,integrated graphic 只剩下把資料從 port 輸出,這個動作就叫做 offload。PRIME 技術就是提供 muxless 的裝置實作 offload 功能。

目前只有 AMD 的顯卡支援這技術[c][d],nvidia 還沒。

案例二:REVERSE PRIME


一個支援 muxless 的系統有兩個顯卡,分別是主要的 integrated graphic 和第二顯卡。輸出 port 在第二顯卡上面。例如 integrated graphic 是內建螢幕和 VGA 輸出,第二顯卡上則有 HDMI 和 display port 輸出,而使用者現在想用 display port 來輸出。

使用者現在想用 display port 來輸出,可是又不想用第二顯卡處理大量運算;因為第二顯卡雖然運算能力比較好,但是比較耗電。也就是說希望第二顯卡負責輸出就好,運算負擔還是 integrated graphic  在處理,只是 port 不是直接由 integrated graphic 控制。Reverse PRIME 技術可以實踐這種設定。


案例三:案例二的進階


一個支援 muxless 的系統有兩個顯卡,分別是主要的 integrated graphic 和第二顯卡。 integrated graphic 是內建螢幕輸出和 VGA 輸出,第二顯卡上則有 HDMI 和 display port 輸出。使用者想要四個 ports 都輸出,但是希望畫面流暢一點。

全部四個 ports 都由 integrated graphic 輸出的話,有可能會不流暢。因此使用者會希望運算盡量都是交給第二顯卡。


實作

案例一:PRIME

列出 provider 資訊

xrandr --listproviders

指定 provider 1 負責運算,provider 2 負責作為 sink output 輸出。(我把這個選項理解成:set provider 1 offload sink output)

xrandr --setprovideroffloadsink 1 0

在 default intel/modesetting driver 中,因為 DRI3 功能已經預設開啟,所以其實上述的設定已經是系統預設了,但手動再做一次並不會怎樣。[b]

這時候只要透過環境變數 DRI_PRIME 就可以動態地切換看是要哪個 provider 去繪圖。例如:

DRI_PRIME=1 <任何執行 render 的指令>

展示使用 provider 0 時(integrated graphic),對應的 opengl 參數 (glxinfo 這個工具可以透過安裝 mesa-utils 來取得)

DRI_PRIME=0 glxinfo

展示使用 provider 1 時(第二顯卡),對應的 opengl 參數

DRI_PRIME=1 glxinfo

這個 merge request 中,checkbox 被加入檢查系統是否具有支援 PRIME 技術的功能;如果有支援,那麼試著在接下來的測試中使用這個技術(同時也是測試這個技術),參見原始碼

從原始碼裡我們可以看到,要下面幾個條件被滿足才會判定系統支援 PRIME 技術,包括:

  • 系統有 amdgpu 這個套件(open source 版本的 AMD 顯卡 driver)
  • Ubuntu 系統是 Xenial
  • 有兩個以上的 GPU

案例二:REVERSE PRIME

略,參見[b]

案例三:案例二的進階

略,參見[b]



參考資料:
[a] https://wiki.archlinux.org/index.php/hybrid_graphics
[b] https://wiki.archlinux.org/index.php/PRIME
[c] https://en.wikipedia.org/wiki/Graphics_Core_Next
[d] https://en.wikipedia.org/wiki/AMD_Radeon_Rx_200_series
[e] xrandr manual