# 2025q1 Homework4 (quiz3+4)
contributed by < `yy214123` >
## [2025 q1 第 3 週測驗題](https://hackmd.io/@sysprog/linux2025-quiz3)
### 測驗 `1`
ceiling division:
任何的整數除法都能如下表示:
$n=dq+r$ $,where:0\leq r<d$
* case 1($r=0$):
$n = dq$
$n/d = q$
$\lceil n/d \rceil=\lceil q \rceil=q$
* case 2($r\neq0$):
$n = dq+r$
$n/d = q+r/d$
$\lceil n/d \rceil=\lceil q \rceil+\lceil r/d \rceil=q+1$
顯然可以用一個 if 判斷式去進行決策,但這以組合語言的角度會多一次分支指令,會是額外的成本。
可以透過加減乘除來達成 ceiling division:
即 $\lceil n/d \rceil=\lfloor(n+d-1)/d \rfloor$
這東西以往都直接背起來了,但我們還是可以證明一下他們等價,這邊我使用矛盾證法:
假設存在 $n,d$ 使 $\lceil n/d \rceil \neq(n+d-1)/d$
設 $n$ 可被 $d$ 整除
> `左式`
則 $\lceil \dfrac{n}{d} \rceil = q$
`右式`
又 $\dfrac{n+d-1}{d} = \dfrac{dq+d-1}{d} = q + \dfrac{d-1}{d}$
由於 $\dfrac{d-1}{d} > 0$
則 $\lfloor \dfrac{n+d-1}{d} \rfloor = q$
**矛盾!**
設 $n$ 不可被 $d$ 整除
> `左式`
則 $\lceil \dfrac{n}{d} \rceil = q + 1$
`右式`
又 $\dfrac{n+d-1}{d} = \dfrac{dq+r+d-1}{d} = q + \dfrac{r+d-1}{d}$
由於 $1 \le r \le d - 1$
則 $r + d - 1 \ge 1 + d - 1 = d$
則 $r + d - 1 \le d - 1 + d - 1 = 2d - 2 < 2d$
所以 $1 \le \dfrac{r+d-1}{d} < 2$
所以 $\lfloor \dfrac{n+d-1}{d} \rfloor = q + 1$
矛盾!
均矛盾故原式成立。
### 測驗 `2`
### 測驗 `3`
## [2025 q1 第 4 週測驗題](https://hackmd.io/@sysprog/linux2025-quiz4)
### 測驗 `1`
在 CRC 中有兩個角色:
* 除數:對應不同長度,會有不同的定義,以這個測驗來說 CRC32C 使用的是 `0x1EDC6F41`。
* 被除數:欲驗證的資料。
兩者進行除法運算的餘數,就會是對應的校驗碼。
XOR 的真值表如下:
| 運算 | 結果 |
| -------- | -------- |
| 0 xor 0 | 0 |
| 0 xor 1 | 1 |
| 1 xor 0 | 1 |
| 1 xor 1 | 0 |
> 若奇數個 1 ,則結果為 1。反之。
使用這個特性,可以透過 xor 來達到多項式取餘數的運算,範例如下:
* 被除數:1101011011
* 除數:10011
```shell
1101011011
10011 (xor)
---------
0100111011
```
拿上次運算的結果再跟除數做一次 xor,除數要對齊 MSB set bit:
```shell
100111011
10011 (xor)
---------
000001011
```
此時剩下 `1011`,其位元數小於除數的 `10011` 所以這就是結果。
可以將被除數與除數轉為對應的多項式來驗證:
* 被除數:1101011011 = $x^9 + x^8 + x^6 + x^4 + x^3 + x + 1$
* 除數:10011 = $x^4 + x + 1$
商為:$x^5+x^4 −2x$
餘為:$x^3+2x^2+3x+1$
而 CRC 是基於 Gf(2) 這個有限域,直白一點來說,可以將各項次的係數 mod 2:
商為:$x^5+x^4 −x$
餘為:$x^3+1x+1$
在 xor 運算中,只會求算出餘數,先前提到的 1011 其相當於 $1*x^3+0*x^2+1*x+1*1$,即為 $x^3+1x+1$。
那也可以都將數字反轉來進行 xor 運算,以先前的例子來說:
```shell
1101011011
10011 (xor)
---------
0100111011
```
實際上要將 10011 後面再補 5 個 0:
```shell
1101011011
1001100000(xor)
---------
0100111011
```
這在運算上會有多餘的計算成本,因為每次要補幾個 0 是不固定的,若反轉運算:
```shell
1101101011
11001(xor)
---------
1101110010
```
本身 `11001` 前面的 0 電腦會為我們補上。剛剛下一步要運算時要去找 MSB set bit ,現在變成找 LSB set bit,我們可以將其與 1 進行 xor,來判斷說是否需要位移,例如 `1101110010`,其 LSB set bit 在由右往左第 `2` 個 bit,此時將其右移一次就能使其移動到第 `1` 個 bit,即可進行下一步操作。
上述的流程呼應了本測驗的此程式碼片段:
```c
for (int bit = 0; bit < 8; bit++)
crc = (crc & 1) ? ((crc >> 1) ^ UINT32_C(0x82f63b78)) : (crc >> 1);
```
將這個迴圈展開會像這樣:
```c
if (bit0 == 1) crc = (crc >> 1) ^ POLY
else crc = (crc >> 1)
if (bit1 == 1) crc = (crc >> 1) ^ (POLY >> 1)
else crc = (crc >> 1)
...
if (bit7 == 1) crc = (crc >> 1) ^ (POLY >> 7)
else crc = (crc >> 1)
```
可如下分析低位元 8 bits:
$b_7\,b_6\,b_5\,b_4\,b_3\,b_2\,b_1\,b_0$
檢查 $b_0$
> 若 $b_0 = 0$ 則 $crc=(crc>>1)\oplus (0x82f63b78)$
> 若 $b_0 = 1$ 則 $crc=crc>>1$
檢查 $b_1$
> 若 $b_1 = 0$ 則 $crc=(crc>>1)\oplus (0x82f63b78)$
> 若 $b_1 = 1$ 則 $crc=crc>>1$
> 其中 $crc$ 是檢查 $b_0$ 後移動過的 $crc$。
依此類推直到檢查到 $b_7$,所以可以發現其實這是一顆二元樹,從 root 開始代表檢查 $b_0$,將左子都當成是 0,右子是 1,第二層開始是檢查 $b_1$,直到最後會有 256 個樹葉。
這 256 個樹葉就分別對應 $b_7\,b_6\,b_5\,b_4\,b_3\,b_2\,b_1\,b_0$ 的所有可能,按照這個性質可以用查表的方式來避免多次迭代及分支的成本。
在看測驗提供的 [util/crc32c.c](https://github.com/qemu/qemu/blob/907209e3111dd62a553a19319b422ff8aba5b9c0/util/crc32c.c#L40)時,我發現其中第 4 行的註解有誤,應該要改成:
```diff
/*
* Castagnoli CRC32C Checksum Algorithm
*
- * Polynomial: 0x11EDC6F41
+ * Polynomial: 0x1EDC6F41
*
* Castagnoli93: Guy Castagnoli and Stefan Braeuer and Martin Herrman
* "Optimization of Cyclic Redundancy-Check Codes with 24
* and 32 Parity Bits",IEEE Transactions on Communication,
* Volume 41, Number 6, June 1993
*
* Copyright (c) 2013 Red Hat, Inc.,
*
* Authors:
* Jeff Cody <jcody@redhat.com>
*
* Based on the Linux kernel cryptographic crc32c module,
*
* Copyright (c) 2004 Cisco Systems, Inc.
* Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
*/
```
如此才與下方 table 的註解一致:
```c
/*
* This is the CRC-32C table
* Generated with:
* width = 32 bits
* poly = 0x1EDC6F41
* reflect input bytes = true
* reflect output bytes = true
*/
```
### 測驗 `2`
### 測驗 `3`