# 2024q1 Homework5 (assessment) contributed by < [ollieni](https://github.com/ollieni) > ## 紀錄閱讀〈因為自動飲料機而延畢的那一年〉的啟發 這篇文章頭尾都有以下這句話 : **人不付出犧牲,就得不到任何回報。如果要得到什麼,就必須付出同等的代價,這就是鍊金術的基本原則,等價交換。當時我們深信著,這就是這世界的真理。------《鋼之鍊金術師》** 這句話是真理,而且我覺得所有人都知道,只是大家都沒辦法照著這個道理去追求自己所想要的事物,究其根本是不想犧牲目前能看到、享受到的好處。 在[第16章](https://blog.opasschang.com/the-story-of-auto-beverage-machine-16/)中提到一些開發軟體系統會遇到的問題,有程式碼的維護性考慮、 framework 厚重程度影響執行速度、如何將整個系統各功能模組化.....,這些都是我們實際在開發時需要去注意的關鍵。 這也讓我想到作者在找合作夥伴時,提到的一句話 **然後我發現一個原本以為只有在資工系發生的現象,那就是「資工系的學生不會寫程式,機械系的學生不會做機械」。** 這句話在目前這個時代好像也適用,至少在我的觀察中,大部分的學生無法開發現實世界中或業界所需要的程式,更別提我們在課堂中學到的一些工程師基本素養,例如怎麼撰寫良好的 commit message 、如何保持一致且易維護的 coding style,我們學到了很多理論但缺乏實作能力。 **經過幾次討論後,為了能在有限的時間和成本下如期完成,我們砍掉大多數的規格,只保留三個最重要的功能。我們要做一台能夠自動加茶、加糖、加冰塊的機器,其餘的封模、珍珠、履帶,通通都不必要,以最小可行產品為優先。** 這段話給我的體會像是我們在有限的時間,去做出老師給的作業,我們需要去考慮我們到底能做多少,而我的狀況是時常做不完,並且品質不到我的標準,這樣的狀況讓我真的能夠做到老師要我們做的 "**誠實面對自己**",可以深刻的體會到自己的不足,重新審視自己,並好好學習。 **硬體設計就是不斷的重複「設計、製造、修正」的循環,想像中的設計會經過有誤差的方式被製造出來,製造出來的產品在現實中運作的效果不如預期,找到問題的根源後再重新修正,機械設計就是重複這樣的循環。只有把東西生出來做實驗,你才會知道該如何改進。** 對於軟體設計來說也是如此,Linux Kernel 到現在也還是在不停的修正,每個版本的 Linux Kernel 都是在先前版本的基礎上進行改進和修正,以應對不斷變化的需求和環境。這種循環過程是開發的本質,並且通過使用者的回饋和不斷的測試,才能不斷地完善和進步。 **苦思之後,我冒出一個奇葩的想法。 葉問曾在洪師父對決拳王時說:「洪師父,不要跟他拼拳,嘗試切他中路。」 PTT上yoyodiy大師曾說:「誰跟你直接暴力破解RAR密碼,我們要繞過去。」 如果問題過於困難無法解決,那就重新定義問題吧** 在我寫作業的時候,會有很相似的狀況,有時候換個角度想,換個方法去解決問題,反而比較有效率和簡單。並且也要注意,要寫出簡潔漂亮的程式,要將問題定義好,不能有偏差影響我們做出精準的解決方法。 **你該學習的不是看到事情要完蛋了就去避免失敗,而是應該學習如何處理與承受失敗,你才能變得比以前更強大。** 這句話我覺得也是真理,也是大部分的人都會知道、會懂的道理,但也是鮮少有人能貫徹。太害怕失敗會讓我們錯失很多機會,而遇到失敗沒有學習如何承受和處理,只會讓我們受挫並沒有任何收穫。在 Linux 核心設計這堂課我遭遇很多失敗與挫折,但是我還是決定要繼續修下去,要好好的面對自己的不足並更加努力學習才是會對於這個挫折最好的處理。 ## 第 1 到第 6 週「課程教材」心得 [Where can we find compiler](https://slide.logan.tw/compiler-intro/#/4/1) 提到一般大學部所教的 compiler ,就是將 code 依序做 lex、parse、syntax-directed translation,但是實際上一個好的 compiler 需要能精準地轉換程式碼,並且有效的運用硬體資源。 [第2章 第9頁](https://slide.logan.tw/compiler-intro/#/2/9),裡面的 tracable 我認為是 traceable。 > With PLT, we know that we can only choose two of (a) covariant type, (b) mutable records, and (c) type consistency. 這句話我不懂,在問了 ChatGPT 後,我了解這是因為有 trade-off 關係,所以三個中只能選兩個。以下為 ChatGPT 的回答: 這句話表明,在設計程式語言或類型系統時,你通常只能將這三個特性中的兩個作為優先考慮。原因如下: > Covariant type 和 mutable records:如果優先考慮共變類型和可變記錄,很難保持類型一致性。修改記錄可能會導致類型的值動態變化,使得很難推斷程序的行為。 > > Covariant type 和 type consistency:優先考慮共變類型和類型一致性是許多靜態類型函數語言中的常見選擇。然而,在保持共變類型和類型一致性的同時引入可變性可能會很棘手,因為變異可能會破壞類型保證。 > > Mutable records 和 type consistency:強調可變記錄和類型一致性可能會導致一種語言設計,其中對可變性進行精心控制,以確保不違反類型規則。這種方法可以在仍然保持強大類型保證的同時提供可變性的好處。 投影片中提到 compiler 有三大 optimization 方向, Scalar optimization(純量優化): 這種優化專注於單個數值操作的優化。它包括將常數摺疊(將在編譯時已知的常數直接替換到運算式中)、刪除冗餘代碼(例如,刪除未使用的變數或計算結果)、以及將運算式轉換為等價但更有效的形式(例如,利用數學等同式簡化運算式)等。 Vector optimization(向量優化): 向量優化將多個純量操作轉換為一個向量操作,以更有效地利用硬體資源和指令集的特性。例如,將多個加法指令組合為一個向量加法指令,從而同時對一組數據進行加法操作,從而提高計算速度和效率。 Interprocedural optimization(程序間優化): 這種優化涉及跨越單個函數或程序的範圍進行優化。它包括函數內聯(將函數調用替換為函數體內的代碼,減少函數調用的開銷)、虛擬函數優化(將虛擬函數的調用轉換為對具體實現的直接調用,從而減少動態分派的開銷)、跨函數分析(在不同函數之間進行相關性分析,以進行更全面的優化)等。 投影片中提到我們做的 final project 和現實產業中編譯器的差異有以下三個重點: Analysis(分析): 在編譯器中,分析是指對程式碼的結構、流程和數據的理解和評估。這包括靜態分析(在不執行程式的情況下對程式碼進行檢查和分析)和動態分析(在程式執行時收集和分析相關數據)。分析的目的是找出程式碼中的模式、依賴和潛在問題,以便進行後續的優化或警告開發人員可能的錯誤。 Optimization(優化): 優化是在編譯器中通過應用各種轉換來改進程式碼的性能和效率的過程。這些轉換可能包括改進算法、減少計算量、消除冗餘操作、提高內存局部性等。優化的目標是使程式碼運行更快,佔用更少的資源,或者在其他方面更好地滿足性能需求,同時保持程式的行為和功能不變。 Intermediate Representation(中間表示): 中間表示是在分析和優化過程中使用的一種數據結構,用於表示程式碼的抽象、中間形式。這個抽象層次比原始程式碼更接近最終生成的機器碼,但比高階程式語言的表示更接近硬體操作。中間表示提供了一個統一的平台,可以在其中進行各種分析和優化,而不受特定語言或硬體平台的限制。它是編譯器中重要的中間步驟,使得編譯器可以更容易地實施各種分析和優化策略。 IR(Intermediate Representation) 非常重要 : 每個前端 (source files; human readable programming language) 直接對應到後端 (machine code) 的話,有太多種組合,勢必會讓開發量爆增。但如果先讓前端輸出 IR,然後 IR 再接到後端,這樣整體的彈性就大多了。 :::info IR 有幾種,多種 IR 是否也造成太多組合,讓開發量爆增? ::: 作者還提到現實世界編譯器的工作有哪些方向: Develop the compiler toolchain for the in-house processors(為內部處理器開發編譯器工具鏈): 開發一個完整的編譯器工具鏈,以支持內部設計的處理器架構。這包括編譯器的各個階段,從前端(例如語法分析和語義分析)到後端(例如代碼生成和優化)。為內部處理器開發編譯器工具鏈的目標是使該處理器能夠有效地執行程式語言代碼,並最大程度地發揮其性能和功效。 :::info 為內部處理器開發編譯器工具鏈是會對每一種程式語言開發嗎?(我認為不太實際,需要耗費太多開發時間) ::: Tune the performance of the existing compiler or virtual machines(調優現有編譯器或虛擬機的性能): 對現有編譯器或虛擬機進行性能優化,以改進其執行程式的速度和效率。這可能包括優化編譯器的代碼生成和優化階段,改進虛擬機的運行時性能,或者調整優化策略以更好地適應特定的程式或硬體環境。這項工作旨在使現有的編譯器或虛擬機能夠更好地滿足使用者的性能需求。 Develop a new programming language or model(開發新的程式語言或模型): 設計並實現一個全新的程式語言或模型,以滿足特定的應用需求或解決特定的問題。例如,NVIDIA 的 CUDA 就是一個針對 GPU 運算的程式設計模型。開發新的程式語言或模型可能涉及設計語法、語意和類型系統,並實現對應的編譯器或執行時系統。這項工作的目標是提供一個更好地適應特定應用領域或硬體平台的程式設計解決方案,從而提高程式的開發效率和執行效率。 我的研究主要是做深度學習在醫學影像上的應用,常常會使用 CUDA ,但是我不了解 CUDA 。 根據我查的資料,CUDA 包括軟硬體環境 : 支持 CUDA 技術的 GPU、運行 CUDA 應用程式所需的操作系統、使操作系統與 GPU 之間能夠協同工作的軟體、CUDA 的 PTX(Parallel Thread eXecution)指令集,控制 GPU 的並行計算。 運作流程是: 1. CPU複製系統主記憶體資料到GPU 2. CPU啟動圖形處理器上的CUDA核心並交付工作 3. 大量CUDA核心同時執行計算程序(kernel)以進行平行運算 4. CPU將計算結果複製回系統主記憶體 參考資料 : [淺談NVIDIA GPU與CUDA技術](https://www.manysplendid.com.tw/%E6%A0%B8%E5%BF%83%E6%8A%80%E8%A1%93/gpu%E9%AB%98%E9%80%9F%E5%B9%B3%E8%A1%8C%E9%81%8B%E7%AE%97/%E6%B7%BA%E8%AB%87nvidia-gpu%E8%88%87cuda%E6%8A%80%E8%A1%93) :::info 我還是不太懂 CUDA 如何串接軟硬體,讓程式可以運用 GPU 資源? ::: ## CS:APP 3/e 心得 檢查是否有加法導致的溢位:兩數相加後的正負號和原本兩者都不同 >bi-endianness (沒打錯,是 bi,而非 "big") 為了提高應用場域的效能和相容性,許多硬體架構如 Power, MIPS, ARM, 可透過特定的切換,支援 big, little 這兩種 byte-order。 :::info bi-endianness 如何切換? > https://developer.arm.com/documentation/den0042/a/Coding-for-Cortex-R-Processors/Endianness ::: ## 想投入的專案 vwifi 虛擬無線網路裝置驅動程式和實驗環境 打造 Linux 虛擬攝影機裝置驅動程式 透過 Netfilter 自動過濾廣告 TODO: https://hackmd.io/@sysprog/linux2024-integration # 以 simrupt 為基礎,建構 [Quiz 13](https://hackmd.io/@sysprog/linux2024-quiz13) 提及的 Pub/Sub 模型,要用到 CMWQ/workqueue TODO: 除了 Pub/Sub 模型的正確性,擴充 simrupt 進行效能分析 (訂閱者數量 vs. 執行時間) > 熟悉 ktime, CMWQ, list