contributed by < grant7163
>
sysprog2019_q1
依據 F02:list 要求。
function call 執行時需 jump 到 functiion 的進入點
實驗觀察使用 function call 與 macro 的執行時間差異,並用 gnuplot 顯示結果
由圖發現當 function / macro 呼叫次數超過 10萬次時, function call 的耗時開始會比 macro 耗時還要高
Linux 應用 linked list 在哪些場合?舉三個案例並附上對應程式碼,需要解說,以及揣摩對應的考量
GNU extension 的 typeof 有何作用?在程式碼中扮演什麼角色?
typeof 會回傳一個傳入參數的資料型態,參數表達可以分為二種形式:
實驗觀察 p, w, y ,z 的資料型態
使用 GDB 觀察 p, w, y ,z 的資料型態
若在 runtime 時執行到 max 會產生2個問題
將 max 改寫成 maxint 的方式可以解決第二個的問題
實驗將 int a, float b 代入 maxint 中,觀察其結果
由 c 印出來的結果發現已經跟傳入時的數值不一致了
再進一步將 int 換成 typeof(a),就可以增加 max 的擴充性,不過傳入變數的資料型態仍需一致性
在更進階的版本,在比大小之前先確認資料型態有沒有一致,若二者資料型態不一致的話, 編譯階段就會丟出 comparison of distinct pointer types lacks a cast 的警告訊息
以下程式碼擷取自 linux/arch/powerpc/boot/types.h
依據 6.1 Statements and Declarations in Expressions 的說明
compound statement ({ …; …; …; })
依據 5.39 Alternate Keywords 的說明
__extension__
__
可以解決關鍵字因為編譯參數 -ansi、-std=c99 等等而失效offsetof
將0強制轉成指向 TYPE 這個資料型態中的 MEMBER ,0 會被當作該 TYPE 的起始地址,然後在以 & 取得 MEMBER 的位址,即可得到 MEMBER 在 TYPE 中的 offest。
在 container_of 的第3行主要行為
再把選定的成員位址減去 offset 就可以取得 structure 的起始位址了。
實驗觀察 container_of 的輸出
輸出結果符合預期,用二種方式得到 node_t newnode 的位址是一樣的
除了你熟悉的 add 和 delete 操作,list.h 還定義一系列操作,為什麼呢?這些有什麼益處?
LIST_POISONING 這樣的設計有何意義?
linked list 採用環狀是基於哪些考量?
list_for_each_safe 和 list_for_each 的差異在哪?“safe” 在執行時期的影響為何?
在 lsit.h 中看到
三種排序的時間複雜度:
名稱 | 最佳 | 平均 | 最差 |
---|---|---|---|
insert sort | |||
quick sort | |||
merge sort |
由圖中發現 random 耗費的時間明顯高於 seq
在範例程式中 quick sort 總是選 head list 的第一個 item 當 pivot
由圖中發現 random 耗費的時間明顯低於 seq
改善 seq 耗費的成本
總是選 head list 的第中間 item 當 pivot
為了降低搜尋在中間位置的 item,在 struct list_head 新增 size 紀錄 array 大小,不過這樣在分類 list_less, list_greater 時都要分別紀錄 size
由圖中發現 seq 耗費的時間有很明顯的降低並略低於 random
時間單位 scale 放大