contributed by <RayPan
>
finalallpass
第一次使用linux作業系統
花了不少時間研究指令
請考慮升級到 Ubuntu 16.04,不然某些軟體套件會太舊 jserv
升級16.04版
$ sudo apt-get update && sudo apt-get dist-upgrade
$ sudo reboot
$ sudo update-manager -d
$ git init
:要開始使用 Git 你必須先建立一個 Git 的 Repository。$ git remote add origin git@github.com:your_account/your_repository.git
:可以連結到遠端的repository。$ git clone git@github.com:Username/repository.git
:可將遠端的repository複製一份到本機,若遇防火牆阻隔問題,請改用HTTPS通訊協定:https://github.com/...
$ git remote -v
:查看working directory所連結的遠端repository。$ git status
:查看目前working directory中所有檔案的情形。$ git add
:將未被git追蹤的檔案加入追蹤,可最後加上.
追蹤全部檔案。$ git commit
:將檔案提交。$ git push
:上傳到遠端repository。$ git pull
:從遠端更新應用程式可以利用 PMU (Performance Monitoring Unit), tracepoint 和核心內部的特殊計數器 (counter) 來進行統計,另外還能同時分析運行中的核心程式碼
perf list
: 印出perf可以觸發哪些eventperf top
: 找出拖慢系統的熱點perf stat
: 已經有個要優化的目標,對這個目標進行特定或一系列的event檢查,進而了解該程序的效能概況。perf stat -r 10 cache-misses ./example
表示對特定程式example執行10次perf其cache-missesperf record
:針對函式級別進行 event 統計,方便我們對程序「熱點」作更精細的分析和優化。target: dependencies
<tab>command
注意:make 在編譯時,若發現 target 比較新,也就是 dependencies 都比 target 舊,那麼將不會重新建立 target,如此可以避免不必要的編譯動作。
.PHONY
: 指定後面的為fake項目,利用.PHONY: clean
來指定clean為fake項目,被視為要建立clean這個檔案,但永不被執行。
MACRO = value
: 可利用$(MACRO)
或${MARCO}
來存取已定義的變數。
:=
: 變數的值決定於它在Makefile中的位置,而不是整個Makefile展開後最終的值。
?=
: 若變數未定義,則替它指定新的值。否則採用原有的值。
$?
: 已被更新的dependencies的值,i.e.dependencies中,比targets還新的值。
$@
: targets的值。
$<
: 第一個dependencies的值。
$*
: targets所指定的檔案,但不包含副檔名。
@
: 不要顯示執行的指令在螢幕上。
-
: 即使該行指令出錯,也不會中斷執行。
-DMACRO
: 指定一個MARCO的名字。
參考資料: Makefile 語法簡介、 猴子都會寫的Makefile
張貼程式碼時,請注意縮排 (空白,而非 tab,與原本程式碼一致的風格) 並且避免單行後方非必要的空白 jserv
延伸閱讀: The Lost Art of C Structure Packing jserv
struct __PHONE_BOOK_ENTRY
struct __PHONE_BOOK_ENTRY
由main.c可知
程式僅透過lastname來查找
其他聯絡人資訊可以放入另一個結構中
如有需要
透過pDetail來索取額外聯絡人資訊
可以減少entry的大小達到優化
修改後程式碼如下
執行看看
在執行程式之前先清空cache:
$ echo 1 | sudo tee /proc/sys/vm/drop_caches
如此entry的大小變可縮小至32bytes
可以發現cache-misses由原本的84.258%下降至44.511%
接著使用makeplot繪製效能比較圖
由於main.c中83行,OPT存在才能輸出opt.txt,所以在phonebook.h中必須#define OPT 1
繪圖如下
避免用圖片來表達文字輸出 jserv
不要只做執行時間的比較,要對照看 cache reference 的差異,拿出你的專業來 jserv
參考共筆:rni c
捨棄原本的sequential search
首先利用hashInitial()
建立hash table
hash table size訂為65537(質數)
結構hashTable內包含tableSize
及list
注意:選擇hashTable大小為質數的原因為
避免hash collison(輸入字串不同,雜湊值相同)
改寫append函式
可以注意到由於findname長度已定義在MAX_LAST_NAME_SIZE
所以將原本strcpy
改為strncpy
可省去比對其他無效字元。
可以發現到
由於須另外建構一個hashtable
append的執行時間會略為上升
但查找時間會大幅下降
cache misses也下降到了38.517%
參考老師提供的Programming Small
執行時間大略相同
但會發現cache-misses可以再下降到26.397%
若有兩個c檔案同時include同一個標頭檔,但要同時編譯成一個檔案,會造成衝突。
參考資料: #ifndef#define#endif的用法(整理) 原作者:icwk
-c
: 只做編譯並生成目標文件。
-g
: 編入除錯資訊(使用gdb時必要)。
-O0
: 不進行優化(注意:是英文字母大歐+零)。
-Wall
: 顯示所有警告訊息。
32bits的電腦,指標大小為4bytes
64bits的電腦,指標大小為8bytes
作業詳細資訊:A01: phonebook
RayPan
A01:Phonebook