--- tags: sysprog2017, sysprog2018 --- # 2018q1 Homework1 (phonebook) contributed by <`HexRabbit`> ### Reviewed by `nashi5566` * 似乎沒有看到輔助說明使用 memory pool 之後的時間變化的比較圖或數據 * 想知道後面提到 malloc() 造成影響與開發環境不同造成優化效果的程度之間有什麼關聯性 (因為列點的方式看起來似乎是有相關聯的) * 作業的標題似乎時間標錯了 ### Reviewed by `LinYunWen` * 同學你的標題錯誤囉~XDDD * commit message 多為使用 ```git commit``` 做較多文字的說明,尤其是在寫入較大量的變更時 * 另外有一個 commit message title 叫 ```Add more bugs``` ([0ed7141](https://github.com/HexRabbit/phonebook/commit/0ed7141d25f13366f1a43cbb64d39fc0a196a974)) ? * 可以多做一些數據上的呈現,比如減少 struct 體積以及 memory pool 那邊,並且分析跟 cache miss rate 上的比較 ## 開發環境 ``` -` .o+` HexRabbit `ooo/ OS: Arch Linux `+oooo: Kernel: x86_64 Linux 4.13.3-1-zen `+oooooo: Virtualization: VT-x -+oooooo+: Intel Core i5-7200U @ 4x 3.1GHz `/:-:++oooo+: L1d cache: 32K `/++++/+++++++: L1i cache: 32K `/++++++++++++++: L2 cache: 256K `/+++ooooooooooooo/` L3 cache: 3072K ./ooosssso++osssssso+` GPU: intel .oossssso-````/ossssss+` RAM: 7862MiB -osssssso. :ssssssso. :osssssss/ osssso+++. /ossssssss/ +ssssooo/- `/ossssso+/:- -:/+osssso+- `+sso+:-` `.-/+oso: `++:. `-/+/ .` `/ ``` ## 優化策略 ### 縮小 struct 體積 額外使用另一個 struct 並只存入 lastName 及指向原 struct 的指針,縮小單筆資料的體積,可使得呼叫 findName() 時讀入快取的資料量增加,繼而增進 cache hit 的成功率。不過由於需要另外建立 struct,在 append 時會耗費更多時間。 ### 使用 Hash Table 參考 [Programming Small](https://hackmd.io/s/SkfffA-jZ),使用一個較大的質數[^1] 42737 作為 HashTable,並以 djb2 作為 hash function,在資料平均分佈的情況下,每個 key 對應的串列長度為(350000/42737 = 8.19),使得每次存取時不必遍歷整個串列,大幅提昇效能。 >1. 請補上參考連結 >2. 為甚麼選定 42737? >[name=課程助教][color=red] >> 已修正,感謝提醒 >> [name=HexRabbit][color=blue] ### 效能差異 ``` Performance counter stats for './phonebook_orig' (100 runs): 9,286,328 cache-misses # 95.053 % of all cache refs ( +- 0.25% ) 9,769,588 cache-references ( +- 0.44% ) 386,432,150 instructions # 1.41 insn per cycle ( +- 0.01% ) 273,745,051 cycles ( +- 0.88% ) 0.088832038 seconds time elapsed ( +- 0.88% ) ``` ``` Performance counter stats for './phonebook_opt' (100 runs): 10,331,405 cache-misses # 78.574 % of all cache refs ( +- 0.59% ) 13,148,653 cache-references ( +- 0.66% ) 448,060,714 instructions # 1.02 insn per cycle ( +- 0.02% ) 438,339,399 cycles ( +- 1.70% ) 0.157374408 seconds time elapsed ( +- 1.51% ) ``` 可以明顯觀察到 cache miss 大幅下降了27%,但總消耗時間上升約77%(大量的free操作於圖表中沒有表現出來) ![](https://i.imgur.com/eDhFLyo.png) >數據跟圖示擠在一起,請重新繪製 >[name=課程助教][color=red] >>搞定 >>[name=HexRabbit][color=blue] findname()消耗的時間大幅度降低, 不過在搜尋單字量為 1 時只能說是完全沒有效能提昇, ![](https://i.imgur.com/JYcRhK8.png) 但如果將單字量增加到 8 個並且有一個單字輸入錯誤的情況下,便可以看出 optimazed 的版本在 findName() 上耗費的時間幾乎沒有改變,而原始版本多了接近三倍時間,可以看出透過犧牲些許效能是有機會在大量查詢人名時得到補償的。 ### 利用 memory pool 提昇速度 在實做了上述幾個優化後,發現優化版本在 append() 上所花費的時間增長了約1.6倍,觀察後發現問題出在 malloc() 和 hash function 上。 嘗試實做 memory pool,透過一次性分配大量記憶體空間來減少 malloc() 呼叫進而縮短執行時間。 ![](https://i.imgur.com/E6uOOk6.png) ``` Performance counter stats for './phonebook_opt' (100 runs): 86,484 cache-misses:u # 13.048 % of all cache refs ( +- 10.91% ) 662,839 cache-references:u ( +- 2.50% ) 178,112,559 instructions:u # 1.63 insn per cycle ( +- 0.03% ) 109,034,011 cycles:u ( +- 0.96% ) 0.051151509 seconds time elapsed ( +- 0.81% ) ``` 效能上有大幅度的提昇,執行時間縮短 40%, cache-reference 和 cache-misses 都大幅度下降,cache-miss rate 降低至 13.048% ## 實做時遇到的問題 - 由於每個人的開發環境不同,優化的效果可能出現差距,例如在我的配備下優化過的append()消耗的時間較原本多出了66%,而在朋友的電腦上實做卻只多出45% + 發現是malloc()消耗相當多時間 --> 利用memory pool解決 - make plot時必須刪除前一次輸出的 opt.txt 才能得出正確結果,否則會使用到上次的數據 + 修改Makefile > 能否請你說明是甚麼問題呢? 我不太理解XD > [name=課程助教][color=red] [^1]: [知乎/Hash时取模一定要模质数吗?](https://www.zhihu.com/question/20806796)