Try   HackMD

2023q1 Homework1 (lab0)

contributed by < eddielin0926 >

:penguin: 作業要求

  • 在 GitHub 上 fork lab0-c
  • 依據上述指示著手修改 queue.[ch] 和連帶的檔案,測試後用 Git 管理各項修改,要能滿足 $ make test 自動評分系統的所有項目。
  • 研讀 Linux 核心原始程式碼的 lib/list_sort.c 並嘗試引入到 lab0-c 專案,比較你自己實作的 merge sort 和 Linux 核心程式碼之間效能落差
  • 確保 qtest 提供的 web 命令得以搭配上述佇列實作使用,目前一旦網頁伺服器啟動後,原本處理命令列操作的 linenoise 套件就無法使用,請提出改善機制
    • 提示: 使用 select 系統呼叫
  • qtest 提供新的命令 shuffle,允許藉由 Fisher–Yates shuffle 演算法,對佇列中所有節點進行洗牌 (shuffle) 操作,需要以統計的原理來分析你的實作,探究洗牌的「亂度」
  • qtest 中執行 option entropy 1 並搭配 ih RAND 10 一類的命令,觀察亂數字串的分布,並運用「資訊與熵互補,資訊就是負熵」的觀念,設計一組新的命令或選項,得以在 qtest 切換不同的 PRNG 的實作 (可選定 Xorshift),搭配統計分析工具,比較亂數產生器 (如 Xorshift vs. 內建) 的品質
  • 研讀論文〈Dude, is my code constant time?〉,解釋本程式的 "simulation" 模式是如何透過以實驗而非理論分析,達到驗證時間複雜度,需要解釋 Student's t-distribution 及程式實作的原理。
    • 注意:現有實作存在若干致命缺陷,請討論並提出解決方案
    • oreparaz/dudect 的程式碼具備 percentile 的處理,但在 lab0-c 則無。
  • 指出現有程式的缺陷或者可改進之處 (例如更全面地使用 Linux 核心風格的鏈結串列 API),嘗試實作並提交 pull request
  • 除了修改程式,也要編輯「作業區」,增添開發紀錄和 GitHub 連結,除了提及你如何逐步達到自動評分程式的要求外,共筆也要涵蓋以下:
    • 詳閱第 1 週所有教材及作業描述 (一), (二), (三), (四), (五),記錄你的啟發和疑惑
    • 開啟 Address Sanitizer,修正 qtest 執行過程中的錯誤
    • 運用 Valgrind 排除 qtest 實作的記憶體錯誤,並透過 Massif 視覺化 "simulation" 過程中的記憶體使用量,需要設計對應的實驗
    • 解釋 select 系統呼叫在本程式的使用方式,並分析 console.c 的實作,說明其中運用 CS:APP RIO 套件 的原理和考量點。可對照參考 CS:APP 第 10 章重點提示
  • 截止日期:
    • Feb 28, 2023 (含) 之前
    • 越早在 GitHub 上有動態、越早接受 code review 並持續改進者,評分越高

:gear: 開發環境

❯ gcc --version
gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0

❯ neofetch --off
eddie@eddie-laptop
------------------
OS: Ubuntu 20.04.5 LTS on Windows 10 x86_64
Kernel: 5.15.79.1-microsoft-standard-WSL2
Uptime: 11 hours, 4 mins
Packages: 1212 (dpkg), 8 (snap)
Shell: zsh 5.8
Theme: Adwaita [GTK3]
Icons: Adwaita [GTK3]
Terminal: /dev/pts/2
CPU: 11th Gen Intel i5-1135G7 (8) @ 2.419GHz
GPU: 6240:00:00.0 Microsoft Corporation Device 008e
Memory: 1455MiB / 7807MiB

:pencil: 開發過程

修改 queue.ch

q_new

struct list_head *q_new()
{
    struct list_head *q = malloc(sizeof(struct list_head));
    if (!q)
        return NULL;
    INIT_LIST_HEAD(q);
    return q;
}

q_free

list_for_eachlist_for_each_safe 的差別在於是否能在迭代的過程中進行刪除,透過額外的指標來記錄下一個節點的位置,讓迴圈能夠繼續進行。

void q_free(struct list_head *l)
{
    if (!l)
        return;
    struct list_head *node, *safe;
    list_for_each_safe (node, safe, l) {
        element_t *el = list_entry(node, element_t, list);
        free(el->value);
        list_del(node);
        free(el);
    }
    free(l);
}

避免張貼完整程式碼,開發紀錄著重於你的想法、遭遇到的問題,以及你如何持續改進程式碼。
:notes: jserv

已移除