# 2024q1 Homework5 (assessment) contributed by < `SimonLee0316` > ## 閱讀〈[因為自動飲料機而延畢的那一年](https://blog.opasschang.com/the-story-of-auto-beverage-machine-1/)〉 閱讀完後深刻體會到再做專案的時候,先做好規劃是很重要的。 在作者沒有夠多的行業知識時,盲目的認為問題很簡單而自己去實做,走了很多冤枉路,且在專案過程中,考慮不夠週到或著資金的問題,都造成了無法持續推動專案前進,但我想這就是學生時代無可避免的,失敗總是貫徹人生始終,但這就是人生,作者再做這個專案時不為了什麼功成名就,就是為了一個自我實現的過程,儘管結果並不怎麼美好,但就因為這些失敗的過程,親自走過的路,都會成為以後的養份,讓自己能夠變得更好。 也替作者感到很高興有這麼幾個很好的夥伴,每個人都有自己擅長的領域,將大家擅長的領域結合在一起才能夠完成這項專案,我認為最應該感謝的是紘銘,他無條件的支持著作者的想法和這個專案,為這個專案挹注資金,甚至在作者延畢時,食衣住行都由紘銘贊助,更不用說買那些高昂的設備,且不求回報,我在紘銘身上看到當初 FACEBOOK 創辦人 [Mark Zuckerberg](https://en.wikipedia.org/wiki/Mark_Zuckerberg) 的共同創辦人 [Eduardo Saverin](https://en.wikipedia.org/wiki/Eduardo_Saverin) 的影子,深感佩服。 ## 學習本課程 5 週之後的感想 還沒修這堂課前,我並不知道 c 語言有這麼多種型態及用法,鑑於我之前有在軟體業實習過的經驗,我認為程式除了正確性之外,可讀性也是很重要的。但在課堂進行過程中,閱讀 linux kernal 程式碼發現除了可讀性,如何將程式寫的**優美**是一門很大的學問,常常會想說一個看似很基礎的操作,為何要將這個操作寫的看起來很複雜,但這都是那些 kernal 開發者所在意的地方,除了正確,效率更是重要。 我對某個題目沒有想法的時候,我常常會看同學的筆記,在閱讀筆記的過程中,理解到如何將筆記寫的能夠讓人**看懂**是很重要的,你寫在筆記裡面的內容,就像是在練習與別的程式設計者協同開發一樣,將真正需要討論或著重要的內容紀錄,而不是像我一樣想到什麼貼什麼,如同老師所說==列出程式碼是為了「檢討」和「便於他人參與討論」,不是用來「假裝自己有付出」==。 做測驗或作業的過程中,我學會了使用 GNU/Linux 開發工具,來對我的程式做分析及實驗,透過這些工具讓我了解到將資料可視化更能讓人了解資料分佈的情況,也可以了解自己寫的程式與他人差距。 ## 紀錄心得和提問 > https://hackmd.io/@sysprog/it-vocabulary 指標篇探討如何使用指標的指標減少多餘的變數宣告。 <s>鍊結</s> 串列篇了解到 liunx 核心風格的鍊結串列,設計非常巧妙,搭配 `container_of` 等巨集,可以做到非常多的操作,之前沒有想過鍊結串列也可以搭配 binary search ,使用快慢指標的方法令我印象深刻。 數值系統篇介紹了許多 bit-wise 的技巧,無論是邏輯/算術運算還是取 log,這都是以前我從未想過的方法,也看到了使用 bit-wise 來省去迴圈。 並行程式設計:排程器原理篇了解到 `coroutine` 的原理及<s>實做</s>方法,使用 setjump/longjmp 來達到 協同式多工,和透過 signal 來達到搶佔式多工的方法。 函式呼叫篇理解函式呼叫以及返回時,記憶體內的各個區域值是如何存放的,以及在操作當中,記憶體回如何變化。 前置處理器篇學到在如何在編譯前透過前置處理器來偵錯,以及他是如何展開我們所定義的巨集。 linux 核心的紅黑樹篇 說明了為何 linux 要使用紅黑樹而不是 AVL 樹,插入和刪除的操作,在刪除的操作看不懂,我的理解是如果刪節點不是 leaf 的話就要拿 successor 來補要被刪的節點,再來就是做平衡。 linux 核心設計:不只挑選任務的排程器 了解到 linux 排程器的發展歷史,了解排程器的時間複雜度是如何從 $O(n)->O(1)->O(logn)$ ,以及為何這些 linux 開發者要持續的改進這些排程器的理由與動機,就算不能真正貢獻到核心,Con Kolivas 還是堅持持續提交他的成果。 ## 想投入的專案 ### Linux 排程器研究 ### 高效網頁伺服器 --- ## 一對一討論 沒有問題 : 收下我的膝蓋 IEEE 754, Assume float is 32-bit. ```clike float float_mul10(float x) { // using bitwise operations; No mul/div union { float f; unsigned u; } conv; conv.f = x; unsigned sign = (conv.u & 0x80000000) >> 31; unsigned frac = conv.u & 0x007fffff; unsigned exp = (conv.u & 0x7f800000) >> 23; unsigned fracmul2 = frac | 0x00800000; unsigned fracmul8 = frac | 0x00800000; fracmul2 <<= 1; fracmul8 <<= 3; fracmul2 += fracmul8; unsigned carry = fracmul2 >> 27; if (carry) { exp += 4; fracmul2 = fracmul2 >> 4; } else { exp += 3; fracmul2 = fracmul2 >> 3; } sign = sign << 31; exp = exp << 23; fracmul2 &= 0xff7fffff; unsigned result = sign | exp | fracmul2; conv.u = result; return conv.f; } ``` * 浮點數 x 乘 10 可以分解成 x * 8 + x * 2 * 可以用 bitwise 完成 * 先將浮點數轉成無號32位元整數,在將 sign bit, exponent bit, fraction bit 分別取出 * 將 x * 8 與 x * 2 分別算出在相加,如果有進位則最後 exponent 要多進一位 誠實面對自己:我連乘十都不會 > 10 = 2 + 8 > TODO: 撰寫程式碼、測試 (e.g., `float_mul10(4.0)`, `float_mul10(4.9)`),附上分析 ```c 4.900000 *10 = 49.000000 49.000000 4.000000 *10 = 40.000000 40.000000 1.720000 *10 = 17.200001 17.199999 ``` futex 有哪些關鍵操作? 1. futex_wait 2. futex_wake 3. futex_requeue TODO: [Quiz8](https://hackmd.io/@sysprog/linux2024-quiz8) 並擴充為 web server,關於測試和效能分析,見 [ktcp](https://hackmd.io/@sysprog/linux2024-ktcp)