# 2025q1 Homework5 (assessment) contributed by < `MuChengChen` > ## [〈因為自動飲料機而延畢的那一年〉](https://blog.opasschang.com/the-story-of-auto-beverage-machine-1) 讀後心得 在這篇文章中,看到作者從幻想創業並做一台自動飲料機,到不斷的實驗試錯,到和不同領域的同學分工合作,到面對挫敗的無力,到和部分的現實妥協,到完成整項專案的整個過程。可以發現作者起初只是要解決更具體且實際的問題,就像是老師上課時提到的諸多專案一樣,目的是改善現有軟體某個功能的效能或是不足之處,然而如同文章中作者遇到的許多問題和挫敗一樣,要做出能運用到現實世界中的系統必定會遇到許多超乎想像的問題,且牽涉的領域很有可能不是單一的領域,需要面對我們不熟悉的領域並和擅長該領域的人共事。我也看到了作者在實作自動飲料機時對於細節的重視,包括考慮食安的問題而選用貴但相對安全的材質,用實驗上百次的數據證明秤冰塊的荷重元誤差是可以接受的等等,這和老師在課堂上一直強調的「對於細節的重視」一樣,若是不重視細節有可能會輕則造成系統效能低落,公司收益受損,重則造成難以估量的危害。 現在的我就如同作者剛開始的情況一樣,尤其是沒有上過作業系統使的情況更加的糟糕,完全跟不上課程,寫測驗題和作業時也是挫敗重重,然而就像老師講的「缺甚麼,補什麼」並且「誠實面對自己」,也被老師在文章中所說的「你該學習的不是看到事情要完蛋了就去避免失敗,而是應該學習如何處理與承受失敗,你才能變得比以前更強大。」所啟發,太害怕失敗會失去成長的機會,反之,勇敢處理與承受失敗才有變強大的可能。 ## 討論議題 1. 在 CPU - Book 1.2.4 章節中提到不管是 32 位元或 64 位元系統核心的 page size 是 4 KiB,那為什麼32 位元系統的 stack size 是 8 KiB,64 位元系統的 stack size 是 16 KiB ? (在第 9 頁的第 18 行, The order of the page size ...... ) ## 問題追蹤 - Q1: Linux 「核心」內的 stack 空間是否會動態調整? 在 Linux 中有 User stack 、 Kernel stack 和 interrupt stack,而 User stack 的空間有可能會動態調整, Kernel stack 則不會,Kernel stack 也是 kernel space 的一部分,所以無法直接被 user process 所使用。當在 32 位元系統時 Kernel stack 大小為 8 KiB, 64 位元系統則是 16 KiB。當一個行程 (process) 被建立時會有對應的 User stack 和 Kernel stack,在 user space 執行時會使用 User stack,然而當行程因為 system call 而轉換到 kernel space 執行時則會使用 Kernel stack。 interrupt stack 則是被用來處理額外的中斷。 ![image](https://hackmd.io/_uploads/S1-KBjrmlg.png) 我們可以使用 `ulimit -s` 查看和改變 User stack 的大小 ``` n96134271@n96134271-ASUS-EXPERTBOOK-B1400CEAEY-B1400CEAE:~$ ulimit -s 8192 n96134271@n96134271-ASUS-EXPERTBOOK-B1400CEAEY-B1400CEAE:~$ ulimit -s 32768 n96134271@n96134271-ASUS-EXPERTBOOK-B1400CEAEY-B1400CEAE:~$ ulimit -s 32768 ``` - Q2: 不依賴分支 (if-else, ?, switch-case, for, while)、迴圈、遞迴的前提,實作 bitcount,亦即計算給定數值的二進位表示中,1 (set) 的總量。 e.g., bitcount(64) = 1, bitcount(65) = 2 利用 bitmask 和 look up table 並且使用 loop unrolling 技巧可以避免使用到分支 ```c //lookup table int num_to_bit_table[16] = { 0,1,1,2,1,2,2,3, 1,2,2,3,2,3,3,4 }; int bitcount(unsigned x) { int i = num_to_bit_table[x&0xF] + num_to_bit_table[(x>>4)&0xF] + num_to_bit_table[(x>>8)&0xF] + num_to_bit_table[(x>>12)&0xF] + num_to_bit_table[(x>>16)&0xF] + num_to_bit_table[(x>>20)&0xF] + num_to_bit_table[(x>>24)&0xF] + num_to_bit_table[(x>>28)&0xF]; return i; } ``` ``` n96134271@n96134271-ASUS-EXPERTBOOK-B1400CEAEY-B1400CEAE:~/linux2025/experiment$ ./bitcount 4294967295 : 32 set bits 2147483647 : 31 set bits 1073741823 : 30 set bits 536870911 : 29 set bits 268435455 : 28 set bits 134217727 : 27 set bits 67108863 : 26 set bits 33554431 : 25 set bits 16777215 : 24 set bits 8388607 : 23 set bits 4194303 : 22 set bits 2097151 : 21 set bits 1048575 : 20 set bits 524287 : 19 set bits 262143 : 18 set bits 131071 : 17 set bits 65535 : 16 set bits 32767 : 15 set bits 16383 : 14 set bits 8191 : 13 set bits 4095 : 12 set bits 2047 : 11 set bits 1023 : 10 set bits 511 : 9 set bits 255 : 8 set bits 127 : 7 set bits 63 : 6 set bits 31 : 5 set bits 15 : 4 set bits 7 : 3 set bits 3 : 2 set bits 1 : 1 set bits ``` - Q3: 資訊科技領域中,何時用得到 bitcount? - 在分析 AES、DES 加密演算法時會使用到漢明距離,例如測量 AES 的擴散特性,而漢明距離的計算就會使用到 bitcount - 在 CIDR 中,CIDR 表示法為一個 IP 地址,一個斜線和一個十進制數字,而十進制數字為網路掩碼從左到右連續的 set bits 計數,因此計算該十進位數字就會使用到 bitcount - Q4: 為何 DRAM 會出錯? DRAM 由於需容納大量的記憶單元,記憶單元中的電容電量很低 ( $10^{-15}$ 法拉或更低),因此只需要很短的時間電容的電量就會被耗盡,需要不斷重複對電容充電,此現象稱為漏電。漏電現象可能會導致資料的遺失,尤其在高溫環境下更為嚴重,因此 DRAM 需定期刷新以確保資料完整性,然而頻繁的刷新會造成 DRAM 資料存取的效能損失。