# 2024q1 Homework5 (assessment)
contributed by < `Hualing-Chiu` >
## 測驗題改進與提問
## 閱讀〈因為自動飲料機而延畢的那一年〉的啟發
在閱讀完此篇文章後讓我感觸很深,並且開始反思自己,作者勇敢的為了創業而選擇延畢,我相信這不是所有人都能擁有的勇氣。
首先,作者在尋找懂機械設計和製造的人時發現了一個問題: 資工系的學生不會寫程式,機械系的學生不會做機械。學校教給學生的理論,有多少人是可以真正把它應用在實作上,派給學生幾個小專案當作作業,相信大多學生的想法都是反正截止日期之前把作業交上去就好,結果對了程式可以跑就好,然後留下了一堆自己看不到的 bug。
再者,「你最大的問題在太害怕失敗了」、「你該學習的不是看到事情要完蛋了就去避免失敗,而是應該學習如何處理與承受失敗,你才能變得比以前更強大。」在文章中看到老師的這些話,彷彿就是在對我說。自己反思過去的求學經歷,確實每次遇到問題都在逃避,害怕自己做不好而不敢挑戰,往往選擇最輕鬆的捷徑。不要害怕失敗,失敗就從中去吸取經驗,這是我現在需要去學習的事情。
## 研讀教材啟發
### [你所不知道的 C 語言:數值系統篇](https://hackmd.io/@sysprog/c-numerics)
#### 電腦不只有二進位
這個部分提到了 balance ternary,與一般三進位不同之處在於 $a = T(-1), 0, 1$,其整數與分數的表示法都跟二進位一樣,但在表示一個數的負數時較二進位方便:
* 二進位
$(6)_{10} = (0110)_2$
$(-6)_{10} = (1010)_2$
* 平衡三進位
$(6)_{10} = (1T0)_{bal3} = 1 \cdot 3^2 + (-1) \cdot 3^1 + 0$
$(-6)_{10} = (T10)_{bal3} = (-1) \cdot 3^2 + (1) \cdot 3^1 + 0$
所以在 balanced ternary 中要取一個數的負數,只要將全部的位元乘以 $-1$ 即可,比二進位的負數操作快速簡單。考慮以下 balanced ternary:
> `+++-0` = (1 * 3^4^) + (1 * 3^3^) + (1 * 3^2^) + (-1 * 3^1^) + 0
> = 81 + 27 + 9 + -3
> = 114
當我們考慮 `-114` 的表示法時,可以發現:
> `---+0` = (-1 * 3^4^) + (-1 * 3^3^) + (-1 * 3^2^) + (1 * 3^1^) + 0
> = -81 + -27 + -9 + 3
> = -114
也就是把所有的 `+` 和 `-` 對調,就不用像在 2 進位表示法中,需要特別考慮 signed 和 unsigned。
balanced ternary 的作用不僅在一致的方式去表達數值,還可用於浮點數。
### [你所不知道的 C 語言: bitwise 操作](https://hackmd.io/@sysprog/c-bitwise)
#### Bitwise Operator
* Set a bit :
```c
unsigned char a |= (1 << n);
```
* Clear a bit :
```c
unsigned char b &= ~(1 << n);
```
* Toggle a bit :
```c
unsigned char c ^= (1 << n);
```
* Test a bit :
```c
unsigned char e = d & (1 << n); //d has the byte value.
```
* The right/left most byte:
```c
unsigned char right = val & 0xff; /* right most (least significant) byte */
unsigned char left = (val >> 8) & 0xff; /* left most (most significant) byte */
```
* sign bit:
```c
bool sign = val & 0x8000; // sign bit
```
### [並行程式設計: 概念](https://hackmd.io/@sysprog/concurrency/%2F%40sysprog%2Fconcurrency-concepts)
#### Concurrency 與 Parallelism
Concurrency 指的是程式架構,將程式拆開成多個可獨立運作的工作,像是驅動程式都可獨立運作,但不需要平行化。
Parallelism 則指程式執行,同時執行多個程式,著重規劃, 將能夠並行的程式,分配給不同硬體單元,使其同時執行。
### [並行程式設計: Atomics 操作](https://hackmd.io/@sysprog/concurrency/%2F%40sysprog%2Fconcurrency-atomics#%E4%B8%A6%E8%A1%8C%E7%A8%8B%E5%BC%8F%E8%A8%AD%E8%A8%88-Atomics-%E6%93%8D%E4%BD%9C)
```c
_Atomic int cnt;
atomic_fetch_add_explicit(&cnt, 1, memory_order_relaxed);
```
> RMW (read-modify-write): 如 `atomic_fetch_add_explicit` 這類的 atomic 操作
通常 CPU 會提供有別於一般 load/store memory 的特殊指令去達成 RMW atomic:
* compare-and-swap (CAS) / swap (SWP):CAS 寫入時同時提供舊值,如果舊值和記憶體裡的相同,就將新值寫入,確保 RMW 的動作完整性
* load-link/store-conditional (LL/SC):這類指令會成對使用,在 LL 讀取記憶體的值,同時標記進入 exclusive 狀態,SC 寫入時清除 exclusive 狀態。在 exclusive 狀態時如有其他 core 較早執行寫入,導致 exclusive 狀態被清除,則忽略這次的寫入並返回失敗。程式可在下一行發現失敗時重新執行 LL/SC 的動作直到成功為止。
#### cache-coherence protocol
這是一個專門處理一至性協定的統稱。在多核處理器的情況下,為了確保所有 CPU 上的 cache 資料是一致的,當某個 CPU 進行寫入操作時,它必須保證其他 CPU 已將資料從他的 cache 中移除 (方可確保一致性),僅在移除操作完成後,此 CPU 才能安全的修改資料。
### [並行程式設計: 實作輕量級的 Mutex Lock](https://hackmd.io/@sysprog/concurrency-mutex)
Futex 可用於實作使用者空間之同步機制,如 mutex、condition variable 等介面都可以藉此實作。
在多個臨界區段 (critical section,簡稱 CS) 之間,使用 mutex 保證互斥性,但無法滿足不同臨界區段之間的前後順序,因此可使**條件變數(condition variable,簡稱 condvar 或 cond)** 在一個臨界區段 A 中等待另一臨界區段 B 的訊號 (signal)。
condvar 不僅是互斥的同步機制,還要一種方式等待其他執行緒進行某些操作。當我們需要在臨界區段 A 中等待臨界區段 B 先完成某些操作時,可用 condvar。
### [事件驅動伺服器:原理和實例](https://hackmd.io/@sysprog/linux-io-model/https%3A%2F%2Fhackmd.io%2F%40sysprog%2Fevent-driven-server)
#### I/O Model
* Blocking I/O
* 基本上,Linux 中大部分的 socket 都是 blocking 的。
* 當user process 呼叫了 `read` 這個system call時, kernel 就會進入 I/O之第一階段: 等待資料準備。大多數情況下, 這個時間點都還沒有資料到達, 甚至是可能發生錯誤了(通常是system call被interrupt signal中斷)。這時候 user process 就會一直處於 blocking 的狀態, 直到 `read` 回傳準備好的資料, 並將資料從 kernel 複製至 user process的 memory, 最後待kernel回傳 OK 給user process後,user process才解除 blocking 的狀態並且繼續運作.
* Non blocking I/O
* 當user process呼叫 `read` 之後, 若 kernel 的資料還沒有準備好, 就不要 block user process了。反之,立刻回傳一個 `error`。
* nonblocking 其實就是 user process 要不斷地去問 kernel 說資料好了沒。這在 application 中的做法, 基本上就是用一個迴圈去一直呼叫 `read`。
* I/O multiplexing
* I/O multiplexing 就是 select / epoll 的行為
* 這種 model 的好處在於使用單個 process/thread 即可同時處理多個網路連接的 I/O。其原理就是 select / epoll 這類的 function 會一直輪詢其所負責監視的 socket,若當中有某個 socket 已經有資料了,就通知 user process。
:::info
I/O multiplexing 的好處是,只用單一執行緒即可「同時處理」多個網路連接的 I/O
* Asynchronous I/O
#### Reactor Pattern
同步的事件循環搭配 non-blocking I/O 又稱為 Reactor pattern
![tmGVoO1](https://hackmd.io/_uploads/B1-Wn434A.jpg)
Reactor pattern 是個設計模式 (design pattern),針對同時處理多個貨單個服務需求。服務處理任務 (service handler) 將傳入的需求拆解,然後分派給相關的請求端處理任務 (request handler)。
#### Edge vs. Level Triggering
`epoll` 的兩種工作模式談起:
1. Edge Triggered (ET, 邊緣觸發)
2. Level Triggered (LT, 條件觸發)
ET 表示在狀態改變時才通知 (例如: 在邊緣上從低電位到高電位),LT 表示在這個狀態才通知 (例如: 只要處於低電位就通知)。對應到 epoll,ET 指一旦有心資料就通知 (狀態的改變),而 LT 是「只要有新資料」就會持續通知,直到緩衝區的資料全數取出。
### [以 sendfile 和 splice 系統呼叫達到 Zero-Copy](https://hackmd.io/@sysprog/linux-io-model/https%3A%2F%2Fhackmd.io%2F%40sysprog%2Flinux2020-zerocopy)
sendfile 系統呼叫的提出,就是克服上述問題,取代 read/write 兩個操作,並減少 context switch 和資料複製的次數:
```c
sendfile(socket, file, len);
```
## 簡述想投入的專案
### 高效網頁伺服器
> 探討從無到有打造 Linux 平台的高效能網頁伺服器,涵蓋是否該將伺服器實作於 Linux 核心內部、並行處理、I/O 模型、epoll、Reactor pattern,和 Web 伺服器在事件驅動架構的考量。
需要研讀的一些教材:
[Linux 核心設計: 針對事件驅動的 I/O 模型演化](https://hackmd.io/@sysprog/linux-io-model/https%3A%2F%2Fhackmd.io%2F%40sysprog%2Fevent-driven-server)
[並行程式設計: 排程器原理](https://hackmd.io/@sysprog/concurrency-sched)
[ktcp](https://hackmd.io/@sysprog/linux2024-ktcp/%2F%40sysprog%2Flinux2024-ktcp-a)
### 開發加速 LLaMA 的 Linux 核心模組
瀏覽今年的期末專案有看到有同學被指派這個題目,我們實驗室本身的研究是對話系統相關的領域,所以 LLaMA 這個大型語言模型在之後的論文或許有機會被應用,因次對這個題目感興趣。
### 並行程式設計
> 回顧[〈並行和多執行緒程式設計〉](https://hackmd.io/@sysprog/concurrency/%2F%40sysprog%2Fconcurrency-concepts)教材和相關測驗題,強化對延伸問題的掌握
---
並行的單向鏈結串列
```c
#include <stdatomic.h>
typedef struct __list {
int val;
struct __list *next;
} list_t;
// **concurrent** add_tail and remove
_Atomic list_t *head = NULL;
```
Head
|
A --> B --> C
|
Tail
1. Remove A
2. Add_tail D (after C)
操作會衝突的狀況:
* 相鄰節點的更新
> TODO: 繼續寫程式並測試
TCP 3-way handshake ?
SYN
https://hackmd.io/@sysprog/SyrtOTNb0
TODO: 第七次作業的 cserv (multiple processes),試著去執行 (含效能評比,要對照 Nginx)
TODO: https://hackmd.io/@sysprog/linux2024-quiz8 和 https://hackmd.io/@sysprog/concurrency-sched (注意看 neco,是 M:N threading model)
TODO: 改寫 cserv,使得其具備 M:N threading model