Try   HackMD

2025q1 Homework1 (lab0)

contributed by <ivan125126>

作業要求

  • GitHub 操作

    • Fork lab0-c
    • 參閱 Git 教學與 GitHub 設定指引(附教學影片)
    • 使用 git log 確認出現 commit c621c4b
  • 程式修改與測試

    • 修改 queue.[ch] 及相關檔案
    • 測試後,使用 Git 管理所有修改,確保 $ make test 自動評分系統通過
    • 在提交前,詳閱《如何寫好 Git Commit Message》
  • 程式設計與優化

    • 研讀「你所不知道的 C 語言: linked list 和非連續記憶體」,並運用(例如 pointer to pointer)技巧精簡程式碼
    • 參閱「2023 年 Linux 核心設計課程第一次作業檢討」及解說影片,注重細節
    • 研讀 Linux 核心原始碼 lib/list_sort.c
      • 嘗試引入專案中
      • 比較自實作的 merge sort 與 Linux 核心版本效能
      • 改進鏈結串列排序效能
    • 詳閱改進 lib/list_sort.c 的解說錄影
  • qtest 命令與隨機性分析

    • 新增 shuffle 命令:使用 Fisher–Yates shuffle 對佇列所有節點進行洗牌,並以統計方法分析其「亂度」
    • 在 qtest 中執行 option entropy 1 並搭配 ih RAND 10 等命令
      • 觀察亂數字串分布
      • 設計新命令或選項以切換不同 PRNG(例如 Xorshift),並利用統計工具比較亂數品質
      • 閱讀參考資料:
        • 「由大數法則理解訊息熵 (entropy) 的數學意義」
        • 「The Linux Pseudorandom Number Generator Revisited」
  • 時間複雜度與實驗驗證

    • 研讀論文〈Dude, is my code constant time?〉
      • 解釋「simulation」模式如何用實驗(非理論分析)驗證時間複雜度,說明 Student's t-distribution 與程式實作原理
      • 討論現有致命缺陷並提出解決方案
  • 程式缺陷與改進

    • 檢查 oreparaz/dudect 中 percentile 的處理,指出 lab0-c 的缺陷或改進處(例如更全面使用 Linux 核心風格的鏈結串列 API)
    • 嘗試實作改進並提交 pull request
      • 若已有其他學員提交,參與討論並提出更佳方案
  • 開發紀錄與工具使用

    • 建立 HackMD 筆記,記錄開發過程與 GitHub 連結,內容包括:
      • 詳閱第 1 週所有教材及作業描述(各部分)的啟發與疑惑
      • 開啟 Address Sanitizer,修正 qtest 執行過程中的錯誤
      • 使用 Valgrind 排除記憶體錯誤,並用 Massif 視覺化 simulation 過程中的記憶體使用量(設計相關實驗)
      • 解釋 select 系統呼叫在本程式中的使用,並分析 console.c 實作
        • 參考 CS:APP RIO 套件與 CS:APP 第 10 章提示

開發環境

$ gcc --version
gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0

$ lscpu
Architecture:             x86_64
  CPU op-mode(s):         32-bit, 64-bit
  Address sizes:          39 bits physical, 48 bits virtual
  Byte Order:             Little Endian
CPU(s):                   16
  On-line CPU(s) list:    0-15
Vendor ID:                GenuineIntel
  Model name:             11th Gen Intel(R) Core(TM) i7-11800H @ 2.30GHz
    CPU family:           6
    Model:                141
    Thread(s) per core:   2
    Core(s) per socket:   8
    Socket(s):            1
    Stepping:             1
    CPU(s) scaling MHz:   57%
    CPU max MHz:          4600.0000
    CPU min MHz:          800.0000
    BogoMIPS:             4608.00
Virtualization features:  
  Virtualization:         VT-x
Caches (sum of all):      
  L1d:                    384 KiB (8 instances)
  L1i:                    256 KiB (8 instances)
  L2:                     10 MiB (8 instances)
  L3:                     24 MiB (1 instance)

第一個遇到的問題

當我在按照作業要求的指引一步步到要push上去的時候,出現了

$ git push 
Username for 'https://github.com': ivan125126
Password for 'https://ivan125126@github.com': 
remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/ivan125126/lab0-c/'

按照它提供的網址查詢後我才知道,如果當初在clone repository的時候用的是

$ git clone https://github.com/你的帳號名稱/lab0-c

git會幫你把這個URL存下來並稱為origin,按照github官網的說法

Password-based authentication for Git has been removed in favor of more secure authentication methods.

這是針對http URL方法的,所以只要改成用SSH URL就沒有問題了。繼續依循著官網找到了解決方案,使用:

$ git remote set-url origin git@github.com:ivan125126/lab0-c

再重新push一次就沒有遇到問題了。


以chatGPT為基礎修改queue.c

目前透過自動評分系統得到的分數是 59/100。

根據作業要求的內容

台大電機系李宏毅教授對於 ChatGPT 的看法是,要善用人工智慧的成果,一旦人們得以善用,人類的書寫不該比 GPT 一類的大語言模型差。

所以我就來更加的「善用」人工智慧了,這是ChatGPT第一次commit還有聊天紀錄,自動評分拿到59分,下面我會一個個檢查GPT寫的函數是否還有改善空間。

q_new()

commit:b2eec1c

以下是GPT所寫:

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

能改善的地方就是malloc()在配置失敗時,就會回傳NULL了,不需要額外寫一個return NULL,於是我修改成如下:

struct list_head *q_new()
{
    struct list_head *head = malloc(sizeof(struct list_head));
    if (head)
        INIT_LIST_HEAD(head);
    return head;
}

q_free()

commit:69a3b35

我沒有給GPT list.h的檔案,導致它沒有使用巨集提昇可讀性。然而,我已經附上queue.h,它卻沒有使用q_release_element(element_t *e):

struct list_head *cur = head->next, *next;
    while (cur != head) {
        next = cur->next;
        element_t *elem = container_of(cur, element_t, list);
        free(elem->value);
        free(elem);
        cur = next;
    }

以下是我使用預定義好的巨集以及函數後改寫:

element_t *elem, *tmp;
    list_for_each_entry_safe (elem, tmp, head, list) 
        q_release_element(elem);
    free(head);

q_insert_head

明明就是直接呼叫q_insert_tail,卻只有q_insert_head一直報ERROR: Probably not constant time or wrong implementation到現在還是找不出原因。