執行人: jerry7961
專題解說影片
可以參考 https://hackmd.io/@sysprog/Syc7ROemA#效能分析
做效能分析
重作第一次作業,並強化若干子任務。
list_sort
量化並分析程式表現 (設計實驗,考慮到資料排序演算法最差的狀況、cache / locality of reference, 資料亂度/分佈)
HackMD 不是讓你張貼完整程式碼的地方,而 GitHub 才是。
你若要張貼程式碼,就必定是因為你想討論或者提出後續的改進。
務必詳細閱讀第一次作業的規範!
q_free
先檢查佇列是否為空,若為空則 return
。
用 list_for_each_entry_safe
巨集走訪所有節點,並釋放節點。
最後釋放開頭節點。
q_insert_head
一開始誤用 strcpy
(如下) 。
strcpy(s1,s2)
的功能是複製字串 s2
到字串 s1
,不會為 s1
分配内存, s1
的長度必須大於 s2
的長度。
因此在沒有為 new_element->value
分配內存的情況下直接用 strcpy(new_element->value,s)
會造成錯誤。
事先為 new_element->value
分配內存再用 strcpy
複製字串即可修正錯誤。
另一種做法是使用 strdup
來代替 strcpy
,strdup
會為字串分配內存空間,並返回新分配空間的指標。
q_insert_tail
與 q_insert_head
的做法類似,差別是改用 list_add_tail
。
q_remove_head
q_remove_head
的作用是從鏈結串列的開頭移除一個元素。
首先檢查 head
是否為空指標,以及鏈結串列中是否至少有一個節點,確保鏈結串列存在且不為空。接著用 list_first_entry
取得鏈結串列第一個元素的指標,並透過 list_del
將這個元素從鏈結串列中移除。
如果 sp
不為 NULL
,使用 strncpy
函式將被移除元素的字串 (to_delete->value)
複製到 sp
指向的位址中。複製的字元數量最多為 bufsize - 1
,這是為了在字串結尾預留一個位置,用來存放 \0
。
q_remove_tail
與 q_remove_head
類似,差別在使用 list_last_entry
來取得要移除的元素。
q_size
使用 list_for_each
來走訪所有節點,每走訪一個節點 count
值就加一。
q_delete_mid
使用快慢指標,快指標每次前進兩步,慢指標每次前進一步。
head
,此時慢指標將指向中間兩個節點中的第二個。為了使 q_delete_mid
能夠刪除中間兩個節點中的第一個,需要增加一個 if
語句來調整慢指標的位置。q_delete_dup
q_delete_dup
是要在鏈結串列已經排序好的狀況下,移走其中具有重複內容的節點。
list_for_each_safe
來走訪鏈結串列中的每個節點。mark_del
用來標記是否遇到重複節點。mark_del
來判斷當前節點是否與前一個節點重複,如果重複則刪除它。mark_del
設為 true
,表示已遇到重複節點。mark_del
為 true
,這表示當前節點與上一個節點內容相同,因此刪除當前節點,並將 mark_del
設為 false
。q_swap
q_swap
的作用是交換鏈結串列中鄰近的節點。
q_swap
從頭部節點的下一個節點開始走訪鏈結串列。對於每對相鄰節點,q_swap
會先將它們從鏈結串列中移除,然後以交換後的順序將它們重新插入到鏈結串列中。這個過程會一直重複,直到走訪完鏈結串列的所有節點。q_reverse
從頭部節點開始走訪鏈結串列,交換每個節點的 next
和 prev
指標以反轉鏈結串列方向,直到走訪完整個鏈結串列。
q_sort
一開始使用 Insertion Sort ,無法通過測資,後來參考同學寫法,改用 Merge Sort 。
q_merge
文字訊息「不要」用圖片展現。
收到,已更正
在 trace-03-ops 出現以上錯誤,經過排查,問題出在 q_merge
函式。原始版本的 q_merge
創建了一個新的 first_queue
指標,它用來指向第一個遇到的非空鏈結串列,這個鏈結串列將作為所有鏈結串列合併的目標,所有其他鏈結串列的元素都會被合併到這個 first_queue
中,其他鏈結串列在合併到 first_queue
後 q
指標會被設為 NULL
,但相關記憶體沒有被釋放,導致錯誤。修改 q_merge
函式後, trace-03-ops 可順利通過。
注意用語:
務必使用本課程教材規範的術語。
收到,已更正
原始版本:
修改版本:
善用 valgrind, massif, perf 等工具
trace-eg.cmd
進行分析留意 I/O Multiplexing Model,務必詳閱 Linux 核心設計: 針對事件驅動的 I/O 模型演化和並行程式設計: 排程器原理