# 2016q3 Homework1 (phonebook) contributed by <`ierosodin`> ## 開發環境 作業系統 : CentOS 7 `$ lscpu` Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 12 On-line CPU(s) list: 0-11 Thread(s) per core: 2 Core(s) per socket: 6 Socket(s): 1 NUMA node(s): 1 Vendor ID: GenuineIntel CPU family: 6 Model: 45 Model name: Genuine Intel(R) CPU @ 3.30GHz Stepping: 5 CPU MHz: 1277.976 BogoMIPS: 6600.19 Virtualization: VT-x L1d cache: 32K L1i cache: 32K L2 cache: 256K L3 cache: 15360K NUMA node0 CPU(s): 0-11 ## 軟體安裝 yum install perf yum install gnuplot [astyle for centos](http://www.melvilletheatre.com/articles/el6/astyle-2.03-3.el6.x86_64.rpm) rpm -ivh astyle-2.03-3.el6.x86_64.rpm ## Astyle To format your file you can execute below command: ``` astyle --style=kr --indent=spaces=4 --indent-switches --suffix=none *.[ch] ``` ## GitHub fork to your GitHub ``` $ git add . $ git commit -m 'Ver.1' $ git remote set-url origin https://github.com/ierosodin/phonebook $ git push origin master ``` ## PhoneBook 效能分析 `$ ./phonebook_orig &perf top -p $!` ``` 21.55% libc-2.17.so [.] __strcasecmp_l_avx 17.30% phonebook_orig [.] findName 6.40% [kernel] [k] clear_page_c 5.79% libc-2.17.so [.] _IO_fgets ``` 熱點發生在strcasecmp( 不斷的比較字串 ) ### 可能的改善方向 老師提到可能的效能改進方向有 * 改寫 struct __PHONE_BOOK_ENTRY 的成員,搬動到新的結構中 * 使用 hash function 來加速查詢 * 既然 first name, last name, address 都是合法的英文 (可假設成立),使用字串壓縮的演算法,降低資料表示的成本 * 使用 binary search tree 改寫演算法 ### 原始Code效能 `$ make run` ``` size of entry : 136 bytes execution time of append() : 0.083056 sec execution time of findName() : 0.007171 sec ``` `$ perf stat --repeat 100 -e cache-misses,cache-references,instructions,cycles ./phonebook_orig` ``` Performance counter stats for './phonebook_orig' (100 runs): 1,990,809 cache-misses # 86.735 % of all cache refs ( +- 0.24% ) 2,295,273 cache-references ( +- 0.11% ) 247,251,886 instructions # 1.11 insns per cycle ( +- 0.02% ) 223,340,345 cycles ( +- 0.24% ) 0.068523391 seconds time elapsed ( +- 0.30% ) ``` ## 嘗試一( phonebook_opt.[ch] ) 發現在search時, 只會使用到last name, 嘗試修改phonebook_opt.h中的`__PHONE_BOOK_ENTRY`, 僅保留`char lastName[MAX_LAST_NAME_SIZE]` ### 效能影響 `$ watch -d -t "./phonebook_opt && echo 3 | sudo tee /proc/sys/vm/drop_caches"` ``` size of entry : 32 bytes execution time of append() : 0.039816 sec execution time of findName() : 0.002610 sec ``` entry縮減到32 bytes, append與fineName時間都有明顯縮短 entry大小會影響到電腦cache的使用 `$ perf stat --repeat 100 -e cache-misses,cache-references,instructions,cycles ./phonebook_opt` ``` Performance counter stats for './phonebook_opt' (100 runs): 365,862 cache-misses # 49.537 % of all cache refs ( +- 0.90% ) 738,568 cache-references ( +- 0.37% ) 224,825,485 instructions # 1.65 insns per cycle ( +- 0.02% ) 136,519,429 cycles ( +- 0.29% ) 0.042013263 seconds time elapsed ( +- 0.37% ) ``` ## 嘗試二( phonebook_hash.[ch] ) 嘗試老師提到的hash function加速查詢 ==需要在Makefile, main.c, calculate.c中作額外的修改== 參考hash tables寫法 : http://algs4.cs.princeton.edu/34hash/ ```clike= int hash = 0; for (int i = 0; i < s.length(); i++) hash = (R * hash + s.charAt(i)) % M; ``` ### 效能影響 `$ watch -d -t "./phonebook_hash && echo 3 | sudo tee /proc/sys/vm/drop_caches"` ``` size of entry : 24 bytes execution time of append() : 0.057173 sec execution time of findName() : 0.000026 sec ``` hash tables可以減少資料的比對次數, 對search的速度有明顯的提升, 但實際使用時, 造成append的時間變長 是否有方法可以使hash tables對append的影響降低? `$ perf stat --repeat 100 -e cache-misses,cache-references,instructions,cycles ./phonebook_hash` ``` Performance counter stats for './phonebook_hash' (100 runs): 269,028 cache-misses # 36.329 % of all cache refs ( +- 0.58% ) 740,533 cache-references ( +- 0.77% ) 213,131,517 instructions # 1.47 insns per cycle ( +- 0.03% ) 145,081,096 cycles ( +- 0.63% ) 0.057804122 seconds time elapsed ( +- 1.17% ) ``` ## 三種版本的比較圖 ![](https://i.imgur.com/8yzvrpN.png)