Skip to main content

· 3 min read

2020 年度個人回顧

  1. 美國工作順利活下來,已達一年六個月
  2. 美國總共搬家四次,其中只有一次跟我有關
  3. 洗衣機卡門事件讓我領悟到世事難料
  4. 年度公開演講 8 場,其中六場是個人自給自足的線上演講。而且有五場是美國時間早上六點起來準時分享。必須說真的滿累的,一大早又要講底層的東西常常會恍神
  5. 年度公開文章 58 篇,其中 30 篇是 2020 參加鐵人賽完賽的文章。今年度有增加更多 devops 相關的文章,也還是有保持幾篇研究 kernel 等底層的文章
  6. 參加 2020 鐵人賽,今年運氣不錯得到佳作,同時團體賽也順利完賽!
  7. 續約微軟 MVP
  8. 開設三門線上課程,講述 kubernetes 各類資訊,課程總長度將近33小時
  9. 參加兩次 podcast 閒聊
  10. 一整年剪頭髮次數: 2 次
  11. 美國遠端工作八個月,回台的14天隔離根本小case
  12. 八個月沒有進入健身房,覺得人生少了一點什麼,實測發現硬舉最大重量少了70公斤 :(
  13. 脫魯
  14. 感謝前國手們的閒聊,最後開設個人粉絲頁分享各類資訊,累積人樹目前 2k

2021 展望

  1. 美國工作繼續順利
  2. 繼續保持線上演講的衝勁與動力,希望至少一年六次
  3. 文章希望內容可以廣度與深度兼具
  4. 今年我要成為 ebpf 王
  5. 繼續參加鐵人賽
  6. 剪頭髮次數: 3 次
  7. 繼續開設三門線上課程
  8. 撰寫第一本書籍
  9. 粉絲頁固定每兩天一篇文章分享長達一年
  10. 街頭健身完成前水平
  11. 保持脫魯

結語

2020 受到疫情影響,導致有八個月的時間都長期遠端工作,整體工作生活習慣改變,包含工作,煮飯,運動等彼此的時間調整。

也因為如此有更多的彈性時間去思考自己要的東西,同時準備課程與鐵人賽文章。整體的時間管理能力目前還算滿意

· 10 min read

2020 年是個多事之秋的一年, COVID-19 於全球肆虐,根據 worldometer 的統計,到 2020/09/25 已經造成全球三千兩百萬人感染,將近一百萬人死亡。其造成的經濟影響更是空球絕後,美國股市一波三折,一年多次熔斷已經是歷史紀錄。企業則是面臨各種收入減少的困境,申請破產與力拼轉型的新聞則是沒有停止過。

今天就來跟大家分享一下,這六個多月以來遠端工作 (Work From Home, WFH) 的一些想法與心得

個人經驗

個人目前對於遠端工作是秉持利大於弊的心得,接下來從不同點來探討利弊

交通

矽谷灣區最著名的一個特色就是塞車,上班塞車,下班塞車,永遠都在塞車,所以過往很多人都會採取彈性上班的方式來避免車流,或是採取大眾運輸工具的方式來通勤。

以我個人為例,過往每天上班的通勤時間大概平均兩個小時,主要分成開車與大眾運輸

  1. 大眾運輸: 腳踏車配上火車通勤,由於火車時刻表固定,所以上下班時間比較沒有彈性
  2. 開車: 開車的話大概可以將時間縮短到單趟 40 分鐘左右,但是整個高速公路都是一片紅,其實開起來很悶

遠端工作後,每天可以省下大約兩個小時的時間,這部分可以拿來上班工作,也可以拿來處理私人事情,時間上更加彈性

工作

遠端在家工作後,最大的幾個變化就是

  1. 工作自律 基本上一整天就是在電腦前面,所以沒有開會的時候,其實都是自己去控制自己的工作節奏,這部分好壞的意見都有聽過,大家也會彼此分享如何讓自己工作更加專心,而不會被家裡的舒適環境給影響。

  2. 會議全面遠端化且數量上升 過往一些小事情要討論時,可能就直接現場約一約,到小會議室直接討論。然而目前則是因為遠端會議,所以全部都要事先預約時間來確保對方目前在電腦前。有時候一個小事情卻要花更多的時間來定案,我個人認為效率是不如過往的。 此外之前也出現如 Zoom Fatigue 這樣的說法,過多的會議內容導致大家開會疲倦,分心

就我個人的心得來看,自己能夠維持好工作的節奏,該完成的工作事項能完成就好,此外被打擾中斷工作的機會也更少了,整體而言利大於弊,

互動

員工之間的會面都是透過線上會議,缺少實體見面的互動,這部分也是見仁見智。有些人不喜歡交流,覺得 「上班當同事,下班不認識」是其工作原則,那應該會滿喜歡這種模式的。但是也有人喜歡實體交流,每天吃個一起吃個午餐,聊聊一些工作以外的事情,分享彼此的事情也都是一種生活。

這部分我就沒有太大意見,有好有壞,偶而還是會透過 slack 與同事聊聊幹話,分享最近的生活,只是少了聲音的互動。

福利

遠端工作以後,公司內本來的福利近乎全滅,什麼咖啡,零食,飲料,冰箱內各種飲品,甚至免費午餐等都不再擁有,一切都要依賴自己處理。

對於一個自住的邊緣人來說,變成每天都要煩惱該怎麼處理今天的飲食,「每餐叫外送,荷包先消瘦」是一個顧慮點,自己煮飯又是一個額外的挑戰,買菜/備料/烹飪/善後四個步驟往往也花費不少時間在處理,如果將這個時間與通勤時間組合起來,未必可以省下時間。

我個人平常就習慣煮飯,已經練就如何快速料理與一次準備多日便當,所以這個情況比較不會有太大問題。 倒是我有聽過朋友因為沒有公司零食的迫害,遠端工作期間被迫減肥,也算是一個附加好處

一個美好的夢想就是辦公室可以縮編,「公司省租金,員工可加薪」

美國現況

疫情以來,各大公司陸陸續續宣布相關的遠端工作政策,而規範的工作日期也隨者疫情的擴散而延後,下面就整理目前我知道部分公司的工作內容,此外政策不一定適用於所有員工,必要性的情況下,部分員工還是要定期前往辦公室。

Apple: 員工可以遠端工作直到 2021 初期 Google: 員工至少可以遠端工作到 2021/07 Facebook: 員工至少可以遠端工作到 2021/07 Twitter: 員工可以選擇永遠遠端工作 Fujitsu: 員工可以選擇永遠遠端工作 Microsoft: 可以遠端工作直到 2021/02 Amazon: 員工至少可以遠端工作到 2021/01 Netflix: 員工遠端工作直到全面接受疫苗

此外,也有人對於遠端工作提出了一些負面說詞,譬如 Netflix 董事長則認為遠端工作沒有帶來正面效果,反而使得討論工作更加困難。

這部分真的就是沒有定案,完全見仁見智,而 Google 最近的調查則顯示只有 10% 不到的員工想要回到過往天天進辦公室的日子,

以下節錄自 Google 官方推特

除了公司本身政策的變動外,居住地遷移最近也是活動頻繁,譬如 Oklahoma 洲則有 Tulsa Remote 計畫,向所有遠端工作者提供一萬美元的獎勵,只要你願意搬來這邊即可。 根據報導指出,舊金山的兩房公寓每個月可能略低於四千美金,而 Tusla 則不到一千美金,再租金花費方面可以說是節省不少開銷。

心得

就我過去五年的台灣工作經驗,我認為台灣公司要跟進遠端工作政策實屬不易,幾個原因如下

  1. 勞基法規定下,公司都要提出員工上下班出勤時間的紀錄,這部分會用來評估是否有加班超時 對於遠端工作者來說,要如何打卡來滿足這些紀錄是一個行政上的問題,而不是技術上的問題 更多時候是公司行政團隊願不願意嘗試探討可能性,並嘗試看看
  2. 沒人監督,老闆放不下 這種情況下,我認為信任是最基本的基礎,老闆信任員工可以遠端工作依然保持良好效率,員工也真的能夠滿足一定的效率來證明制度可行。過往就有聽過台灣發生過老闆接受遠端工作,結果員工私下兼差來賺錢,最後兩邊信任破壞,一切回歸辦公室制度。

Reference

· 4 min read

本身算是 Costco 愛好者,每個禮拜的蛋白質基本上都是從 Costco 取得

常買的有

  1. 雞胸肉
  2. 雞腿排
  3. 牛奶
  4. 蛋白丁
  5. 蝦仁
  6. 鮭魚

這篇文章主要用來記錄冷凍鮭魚排的資訊,每一份的大小以及熱量等資訊

來源

Costco 基本上有滿多的鮭魚可以購買,有在冷藏處比較新鮮的挪威鮭魚,也有在冷凍庫的冷凍鮭魚。 由於我大部分都是製作便當,因此任何的食材在烹飪完畢後都會冷藏並且隔天透過微波爐來加熱飲食 因此在選擇上我都還是以冷凍鮭魚為主,只有特別想要當天吃才會選擇冷藏鮭魚

本篇主要以冷凍鮭魚為主,其包裝如下 Imgur

大小

根據 Imgur 包裝背後的標示,本包裝大概含有 2KG 的鮭魚,然而實際上裡面的包裝物並不是真的如其所說有 20 份這麼多,其實每片鮭魚大小都頗大的。

實際上拿出一片使用電子秤來進行實測,測出來的重量大概是 300g 左右 Imgur

因此一整包的份量大概會落在7片左右,畢竟每片鮭魚的大小都會有點差距,不過大概可以記住一片300g就好

營養

本篇就直接使用該包裝背後所提供的成份表來計算每片鮭魚排的營養素 Imgur

將常見的營養素基於 100 以及 300 公克列舉出來

100公克300公克
熱量149 KCal447 KCal
蛋白質17.9 g53.7 g
粗脂肪8.5 g25.5 g
飽和脂肪2.2 g6.6 g
碳水化合物0.1 g0.3 g
59 mg177 mg

這樣來看如果今天一餐吃一片冷凍鮭魚排的話,,攝取的蛋白質大概是 54 g 左右,熱量450卡,如果單純考慮價錢與蛋白質的比例的話,還是雞胸/雞腿的比例比較好,不過換換口味吃個鮭魚也不錯

烹調

基本上好好的煎就沒有什麼問題了,唯一要注意的是要確認內部比較厚的部分需要比較長的時間才會熟透,可以切半去料理會比較快。

· 3 min read

本身算是 Costco 愛好者,每個禮拜的蛋白質基本上都是從 Costco 取得

常買的有

  1. 雞胸肉
  2. 雞腿排
  3. 牛奶
  4. 蛋白丁
  5. 蝦仁
  6. 鮭魚

這篇文章主要用來記錄雞腿排的資訊,包含來源,熱量等資訊

來源

基本上 Costco 雞腿肉的來源有兩家,分別大成 以及 卜蜂 這兩家供應商。

購買時包裝上面都會顯示這兩家的名稱與Logo,除了供應商名稱不同外,其價格與大小大致上並沒有差異。

大小

根據 Costco 線上官網 的圖示說明,每包 Costco 去骨雞腿都是一次六包為一個單位

如下圖

六包的重量大概都是落在 2.5kg 上下左右,平均下來每包平均 400多克左右。

但是實際上在食用時,每一包內的去骨雞腿牌數量則是 2-3 片,這部份就是隨機的。

為了能夠簡單的估算每一包雞腿排的營養素,我們必須要先知道每一塊的重量

這邊實際拿電子秤來實測看看這兩片雞腿排的重量

Imgur Imgur

根據上述的結果,每片雞腿排的重量大概落在 170 公克左右

營養

根據食品藥物消費者知識服務網 提供的食品營養素估算表

我們使用肉類->雞類 ->清腿 這個分類來估算營養成分

將常見的營養素基於 100 以及 170 公克列舉出來

100公克170公克
熱量157267
粗蛋白18.531.4
粗脂肪8.714.8
飽和脂肪2.54.3
總碳水化合物00

這樣來看如果今天一餐吃包,攝取的蛋白質則介於 60 ~ 90 公克之間,取決於你那一包裡面有多少片雞腿排

烹調

雞腿肉相對於雞胸肉來說料理非常簡單,基本上只要現煮(烤/煎/)等各式料理方法都不會太難吃,所以就邊就不多述相關的料理方式了

#參考來源

· 7 min read

blktrace is a block layer IO tracing mechanism which provide detailed information about request queue operations up to user space.

blkparse will combine streams of events for various devices on various CPUs, and produce a formatted output the the event information. It take the output of above tool blktrace and convert those information into fency readable form.

In the following, We will use those tools blktrace and blkparse to help us to observe sector numbers which has been written by fio requests. We will use the fil to generate two diffenrt IO pattern requests, sequence write and random write.

Environment

OS: Ubuntu 14.04 Storage: NVME FIO: fio-2.19-12-gb94d blktrace: 2.0.0 blkparse: 1.1.0

you can use following commands to install blktrace and blkparse

apt-get install -y blktrace

Experiment

Step1

In order to make the output of blkparse more easily to read, we set the numjobs to 1. Following is my fio config

[global]
iodepth=256
numjobs=1
direct=1

time_based
runtime=120
group_reporting
size=5G
ioengine=libaio

filename=/dev/nvme1n1
[rw]
bs=4k
rw=randwrite

[sw]
bs=64k
rw=write

After we setup the fio config, use the fio to generate the IO request. In this example, we ask the fio to generate the IO via sequence write pattern.

fio ${path_of_config} section=sw

During the experiment, you can use the tool iostat to monitor the I/O information about the device we want to observe.

Step2

Open other terminal and use blktrace to collection the data, there are two parameter we need to use, First one is -d, which indicate what target device blktrace will monitor to. Second, is -w, we use it to limit the time (seconds) how long blktrace will run. So, our final command looks like below.

blktrace -d /dev/nvme1n1 -w 60

In the end of blktrace, you can discover some new files has created by blktrace and its prefix name is nvme1n1.blktrac.xx The number of files is depends how may CPUs in your system.

-rw-r--r--  1 root     root         821152 Jun  2 10:39 nvme1n1.blktrace.0
-rw-r--r-- 1 root root 21044368 Jun 2 10:39 nvme1n1.blktrace.1
-rw-r--r-- 1 root root 462864 Jun 2 10:39 nvme1n1.blktrace.10
-rw-r--r-- 1 root root 737960 Jun 2 10:39 nvme1n1.blktrace.11
-rw-r--r-- 1 root root 865872 Jun 2 10:39 nvme1n1.blktrace.12
-rw-r--r-- 1 root root 755248 Jun 2 10:39 nvme1n1.blktrace.13
-rw-r--r-- 1 root root 4675176 Jun 2 10:39 nvme1n1.blktrace.14
-rw-r--r-- 1 root root 4471480 Jun 2 10:39 nvme1n1.blktrace.15
-rw-r--r-- 1 root root 5070264 Jun 2 10:39 nvme1n1.blktrace.16
-rw-r--r-- 1 root root 5075040 Jun 2 10:39 nvme1n1.blktrace.17
-rw-r--r-- 1 root root 5062104 Jun 2 10:39 nvme1n1.blktrace.18
-rw-r--r-- 1 root root 5586936 Jun 2 10:39 nvme1n1.blktrace.19
-rw-r--r-- 1 root root 3718848 Jun 2 10:39 nvme1n1.blktrace.2

Step3

Now, we can use the blkparse to regenerate human-readable output form the output we get via blktrace before.

We need to indicate source files, you can just use the device name without .blktrace.xx, for example, nvmen1, it will search all files which match the pattern nvmen1.blktrace.xx and put together to analyze. Then, the -f option used to foramt the output data, you can find more about it via man blkparse

OUTPUT DESCRIPTION AND FORMATTING
The output from blkparse can be tailored for specific use -- in particular, to ease parsing of output, and/or limit output fields to those the user wants to see. The data for fields which can be output include:

a Action, a (small) string (1 or 2 characters) -- see table below for more details

c CPU id

C Command

d RWBS field, a (small) string (1-3 characters) -- see section below for more details

D 7-character string containing the major and minor numbers of the event's device (separated by a comma).

e Error value

m Minor number of event's device.

M Major number of event's device.

n Number of blocks

N Number of bytes

p Process ID

P Display packet data -- series of hexadecimal values

s Sequence numbers

S Sector number

t Time stamp (nanoseconds)

T Time stamp (seconds)

u Elapsed value in microseconds (-t command line option)

U Payload unsigned integer

For our observation, we use %5T.%9t, %p, %C, %a, %S\n to format our result containing timestamp, command, process ID, action and sequence number.

Since the data I/O contains many action, such as complete, queued, inserted..ect. we can use option -a to filter actions, you can find more info via man blktrace. In this case, we use the write to filter the actions.

In the end, use the -o options to indicate the output file name.

barrier: barrier attribute
complete: completed by driver
fs: requests
issue: issued to driver
pc: packet command events
queue: queue operations
read: read traces
requeue: requeue operations
sync: synchronous attribute
write: write traces
notify: trace messages
drv_data: additional driver specific trace

The command will look like below and it will output the result to file output.txt.

blkparse nvme1n1 -f "%5T.%9t, %p, %C, %a, %S\n"  -a write -o output.txt

open the file, the result looks like

    0.000000000, 22890, fio, Q, 1720960
0.000001857, 22890, fio, G, 1720960
0.000005803, 22890, fio, I, 1720960
0.000009234, 22890, fio, D, 1720960
0.000036821, 0, swapper/0, C, 1996928
0.000067519, 22890, fio, Q, 1721088
0.000068538, 22890, fio, G, 1721088
0.000071531, 22890, fio, I, 1721088
0.000073102, 22890, fio, D, 1721088
0.000093464, 0, swapper/0, C, 1994624
0.000123806, 0, swapper/0, C, 1785472
0.000147436, 22892, fio, C, 1784576
0.000159977, 22891, fio, C, 1997312
0.000166653, 22891, fio, Q, 2006912
0.000167632, 22891, fio, G, 2006912
0.000169422, 22891, fio, I, 2006912
0.000171178, 22891, fio, D, 2006912
0.000188830, 22892, fio, Q, 1817728
0.000189783, 22892, fio, G, 1817728
0.000191405, 22892, fio, I, 1817728
0.000192830, 22892, fio, D, 1817728
0.000202367, 22891, fio, Q, 2007040
0.000203160, 22891, fio, G, 2007040
0.000205969, 22891, fio, I, 2007040
0.000207524, 22891, fio, D, 2007040
0.000227655, 22892, fio, Q, 1817856
0.000228457, 22892, fio, G, 1817856
0.000231936, 22892, fio, I, 1817856
....

Since the fio will fork to two process to handle the process, we use the grep to focus on one specific process (pid=22892).

grep "22892, fio" output.txt | more

Now, the result seems good, we can discover the sequence number (fifth column) is increasing. One thing we need to care about is the row which action is "C", which means the completed, since we don't know how NVME handle those request and reply to upper layer. we only need to focus on other action. such as "Q (queued This notes intent to queue i/o at the given location. No real requests exists yet.)" or "I (inserted A request is being sent to the i/o scheduler for addition to the internal queue and later service by the driver. The request is fully formed at this time)".

    0.000147436, 22892, fio, C, 1784576
0.000188830, 22892, fio, Q, 1817728
0.000189783, 22892, fio, G, 1817728
0.000191405, 22892, fio, I, 1817728
0.000192830, 22892, fio, D, 1817728
0.000227655, 22892, fio, Q, 1817856
0.000228457, 22892, fio, G, 1817856
0.000231936, 22892, fio, I, 1817856
0.000233530, 22892, fio, D, 1817856
0.000360361, 22892, fio, Q, 1817984
0.000361310, 22892, fio, G, 1817984
0.000364163, 22892, fio, I, 1817984
0.000366696, 22892, fio, D, 1817984
0.000536731, 22892, fio, Q, 1818112
0.000537758, 22892, fio, G, 1818112
0.000539371, 22892, fio, I, 1818112
0.000541407, 22892, fio, D, 1818112
0.000670209, 22892, fio, Q, 1818240
0.000671345, 22892, fio, G, 1818240
0.000673383, 22892, fio, I, 1818240
0.000676260, 22892, fio, D, 1818240
0.001885543, 22892, fio, Q, 1818368
0.001887444, 22892, fio, G, 1818368
0.001891353, 22892, fio, I, 1818368
0.001895917, 22892, fio, D, 1818368
0.001934546, 22892, fio, Q, 1818496
0.001935468, 22892, fio, G, 1818496
0.001936891, 22892, fio, I, 1818496
0.001938742, 22892, fio, D, 1818496
0.001965818, 22892, fio, Q, 1818624

Now, we can do all above command again and change the section to rw for fio using the randon write pattern. The blkparse result will show the random sequence number.

Summary

In this article, we try to use tools blktrace and blkparse to analysiz the block level I/O for fio request. We observe the filed sequence number to make sure thhat the fio can generate the sequence or random according to its config.

Reference

· 5 min read

本文主要嘗試分析 drbd(9.0) 於 kernel運行時的效能分析,希望藉由 perf 這個 tool 來分析整個程式運行的狀況,藉此觀察其運行時各 function 的比例。

Testing Environment

為了進行效能上的分析,首要條件就是先將 DRBD 給衝到效能瓶頸才有機會去觀察,所以本文採用下列的環境與工具來進行這項作業

Environment

CPU: Intel(R) Xeon(R) CPU E5-2695 v3 @ 2.30GHz Storage: Non-Volatile memory controller(NVME) Tool: fio OS: Ubuntu 16.04 with linux 4.4.0-78-generic

Setup

為了更方便觀察 drbd 的運行,我們將 drbd 創造的 kernel thread 都分別綁在不同的 cpu 上,這樣可以讓每隻 kernel thread 盡可能去使用cpu。

  1. 透過 ps or htop 取得 kernel thread 的 pid,這邊可以關注的有
    • drbd_s_r0 (sender)
    • drbd_r_r0 (receiver)
    • drbd_as_r0 (ack sender)
    • drbd_a_r0 (ack receiver)
    • drbd_w_r0 (worker)
  2. 透過 taskset 這個指令將上述程式分別綁到不同的 cpu 上
taskset -p 0x100 18888
...

Stress

本文使用 fio 來進行資料的讀取,下方提供一個簡易的 fio 設定檔,可依照自行的環境變換修改。

[global]
iodepth=512
numjobs=3
direct=1

time_based
runtime=30
group_reporting
size=5G
ioengine=libaio

filename=/mnt/beegfs/fio1.test
[rrw]
bs=4k
rw=randrw
rwmixread=75

[rr]
bs=4k
rw=randread

[rw]
bs=4k
rw=randwrite

[sr]
bs=64k
rw=read

[sw]
bs=64k
rw=write

我們 fio 採用 client/server 的架構,要是可支援多台 client 同時一起進行資料讀取,提供更高的壓力測試。

假設該設定檔名稱為 fio.cfg,並且放置於 /tmp/fio.cfg 則首先在 node-1 上面執行下列指令以再背景跑一個 fio server

fio -S &

接下來要運行的時候,執行下列指令來運行 fio,其中若想要改變測試的類型,可透過 --secion進行切換。

/fio --client=node-1 /tmp/fio.cfg --section=rw

這時候可以透過 htop 以及 iostat 的資訊去觀察,如下圖 當前透過 iostat 觀察到的確對 drbd0 有大量的讀寫動作 同時由 htop (記得開啟 kernel thread觀察功能),可以看到 drbd_s_r0 以及 drbd_a_r0 都各自吃掉一個 cpu,大概都快接近 100% 的使用率。

Profile

有了上述的環境後,我們就可以準備來分析 drbd 程式碼運行狀況。

Environemnt

這邊使用 perf 這套程式來分析,基本上 kernel 新一點的版本都已經內建此功能了,比較舊的 kernel 則需要自己重新開啟該 kernel config然後重新 build kernel,所以這邊使用 Ubuntu 16.04 with linux 4.4.0-78-generic 相對起來非常簡單。

直接執行 perf 這個指令,若系統上有缺少 linux-tools-4.4.0-78 相關 tool 的話會有文字提示你,如下所示,按照提示使用 apt-get 將相關的套件安裝完畢後,就可以使用 perf 了。

WARNING: perf not found for kernel 4.4.0.78

You may need to install the following packages for this specific kernel:
linux-tools-4.4.0-78-4.4.0-78
linux-cloud-tools-4.4.0-78-4.4.0-78
Run

perf 的功能非常強大,可以參考 wiki, 這邊我們使用 perf top 的方式來觀察結果。 為了可以順便觀看 call graph 的過程,再執行perf的時候要多下-g這個參數

指令為 perf top -g -p $PID,如 perf top -g -p 18888

在這邊我嘗試觀察 drbd_a 這隻,結果如下列

drbd_a

這邊可以觀察到三隻吃比較兇的 function 都吃很兇,分別是 native_queue_spin_lock_slowpathtr_release 以及 idr_get_next

這邊比較麻煩的是你看這個只能知道就是卡在 spin_locK,系統上是不是 multithread,然後有太多的資料要搬移導致 spin_lock ? 這些搬移的資料是誰放進去的?,這些資料是什麼?

以及更多的問題都必須要看程式碼去理解其整體設計架構,才有辦法講出一套完整的流程說明這個結果。

這部份等之後能夠完整理解整個 drbd 的 write-path 或是 read-path 時再重新來看一次這張圖,到時候應該會有完全不一樣的思維。

· 2 min read

不久前有一篇文章https://daniel.haxx.se/blog/2017/04/22/fewer-mallocs-in-curl/指出, curl 開發者嘗試將 malloc 呼叫的次數減少,結果對整體的影響帶來的顯著的提升

使用 curl http://localhost/512M 當作第一個比較 原始版本的 curl 關於 malloc 相關數據如下

Mallocs: 33901
Reallocs: 5
Callocs: 24
Strdups: 31
Wcsdups: 0
Frees: 33956
Allocations: 33961
Maximum allocated: 160385

而修改後的版本為

Mallocs: 69
Reallocs: 5
Callocs: 24
Strdups: 31
Wcsdups: 0
Frees: 124
Allocations: 129
Maximum allocated: 153247

比較起來可以發現, malloc 呼叫的次數有急遽的下降,從 33901 降落到 69,而整體使用的記憶體也少了 7KB 左右 此外,若比較兩者傳輸的速度,抓取一個 80GB 的檔案

Original: 2200MB/sec
Modified: 2900MB/sec

在傳輸方面提升了 30% 左右的速率,非常驚人 若使用 time 指令來比較新舊版本抓取 80G 檔案的差別

Old code:

real 0m36.705s
user 0m20.176s
sys 0m16.072s
New code:

real 0m29.032s
user 0m12.196s
sys 0m12.820s

修改相關的 commit 如下

簡單來說就是將 malloc 的部分都拔除,盡量使用 stack 來提供記憶體,藉此減少呼叫 malloc 的部分。 主要是因為 curl 在傳輸的過程中,會有非常大量且小空間的 malloc 被呼叫到,這部分拖慢的整體的運行速度

· 2 min read

314 Binary Tree Vertical Order Traversal

原題目是付費題目,有興趣看到完整的請自行付費觀賞,在此就不提供超連結了。

Introduction

  • 給定一個 binary tree,將此 tree 以 vertical 的方式走過,
  • 輸出時,從最左邊開始輸出
  • 相同 colume 的算同一個 group,若屬於同 row 且同 colume,則從左邊開始算起

Example

        0
/ \
1 4
/ \ / \
2 35 6
/ \
7 8

輸出為 [2][1] [0,3,5][4,7] [6][8]

Solution

這題不太困難,基本上可以採用 BFS 來搜尋整個 tree,然後加入一個 index 的欄位,root 的 index 是 0,往左遞減,往右遞增,在 BFS 的過程中,就把相同 index 都收集起來,最後再一口氣輸出即可。

pseudo code 如下

queue.push(pair(0, root));
while (!queue.empty()) {
index = queue.front().first;
node = queue.front().second;

ans[index].push(node->val)

if (node->left)
queue.push(pair(index-1, node->left);
if (node->right)
queue.push(pair(index+1, node->right);
}

return ans;

· 6 min read

還記得以前在工三讀書時,常常看到 Chun Norris 坐在我前面,然後畫面上是一張一張的卡片在不停地翻動,每張卡片上面都標記者一個日文單字, 看他快速地翻閱這些卡片,感覺就是在背頌單字,那時候也就沒有去想太多了。

沒想到過了幾年後,Chun Norris 竟然出書了!!! 英、日語同步Anki自學法:我是靠此神器,最短時間通過日檢N1、多益975分

看到這個消息後,就馬上預購了一本這個書,不但捧朋友的場,同時也順便瞭解看看到底 Anki 是什麼樣的東西。

對於想瞭解 Anki 基本操作的,可以參考這邊 經過了一陣摸索後,也開始使用了 Anki 來幫助我背單字,不過由於內建的一些卡片集(Deck)大都偏向特定主題,如托福、多益等 ,所以我後來也自己創建了一個卡片集給我自己使用。 在卡片編輯的部分,原本都是透過Anki application上面的 GUI 去操作編輯,填寫正反兩面的卡片資訊。 所以本來的流程是這樣

  1. 我看小說/文章
  2. 使用手機的 APP 去查詢單字
  3. 定期開啟 Anki 將 APP 內的歷史單字一個一個透過線上字典服務去查詢
  4. 將查詢的結果複製貼上到 Anki內,並轉成Anki的卡片

上面第三步驟最花費時間,當卡片數量一多的時候,其實要非常可怕的 那時候APP內大概有五六百個查詢過的單字,每個單字花20秒去填寫,也要整整三個小時不間斷才有辦法處理完畢。

有鑑於未來單字量只會愈來愈多,這樣手動下去實在不是辦法,因此腦筋就轉了彎一下,看有沒有辦法讓上面的步驟簡單化 上述(1),(2)這兩個步驟是不可避免的,那(3),(4)這兩個步驟就是主要處理的對象了。

針對我的目標,我將其拆成兩部分

  1. 給定一個單字,想辦法自動獲得其發音解釋
  2. 從上述的輸出中,將其自動變成 Anki 的卡片,然後塞到我的卡片集(Deck)中

針對第一點,我使用 python 作為我的程式語言,然後很偷懶的就拿了 yahoo 字典當作我的搜索來源 於是用了 python + BeautifulSoup + urllib 來爬網頁, 於是就網頁爬阿爬~就爬出了發音解釋了,這邊一切搞定

再來第二點,想要自動加入倒 Anki 的資料庫中,於是就到github去翻一翻,還真的翻到有人寫好已經可以用的工具 addToAnki,這個作者使用 python 撰寫,提供一個 tool 讓第三方可以將卡片的內容輸入進去後,自動轉為卡片並且塞到對應的卡片集中。 雖然我個人是更偏向去呼叫 library 而不是只接呼叫 tool 來處理,不過我的目的能達成就好,所以就將我前面的程式碼跟他的結合起來。目前將此結果放在這邊 同時我也發送了一個 pull request 到原先作者那邊,把我的使用情境當作一個多的範例使用,不過我看作者也兩三年沒碰了,應該也不會去接收我的 PR XDD

最後我的流程就是

  1. 遇到不會的單字
  2. 使用手機查詢單字
  3. 定期將查詢過的單字匯出成一個文字檔
  4. 將該文字檔送給我的 python 去處理,等他自動處理好即可。

上次一口氣加了四百多個單字,總共花費十五分鐘左右,大部分的時間應該都是消耗再去爬 yahoo dict這邊,目前這樣已經滿足我的需求。

· 2 min read

Basic

  • commit所使用的編輯器會依照下列優先度去選擇,

    1. GIT_EDITOR 環境變數
    2. core.editor 的設定
    3. VISUAL 環境變數
    4. EDITOR 環境變數
    5. vi 指令
  • 變動檔案請用 git mv,使用git rm要注意檔案系統內的檔案會被真的刪除。

  • git log可以列出簡略的coommit資訊

  • git show [commit id] 可以看詳細的commit資訊,可以加上commit ID來指定特定的commit

  • git show-branch --more=10 可以看當前bracnh的詳細commit資訊,由--more控制數量

Configuraion

總共有三種設定方式,優先度如順序

  • .git/config, 可以用 --file或是預設的方式操作
  • ~/.gitconfig, 可以用 --global操作
  • /etc/gitconfig,可以用 --system操作
git config --global user.name "hwchiu" (2)
git config user.email "[email protected]" (1)
  • 可以透過 git config -l列出當前所有的設定
  • 可以透過 --unset來移除設定
git config --unset --global user.name