# [2020q1](http://wiki.csie.ncku.edu.tw/linux/schedule) 第 5 週測驗題 ###### tags: `linux2020` :::info 目的: 1. 檢驗學員對 **[bitwise 操作](https://hackmd.io/@sysprog/c-bitwise)** 和 **[數值系統](https://hackmd.io/@sysprog/c-numerics)** 的認知; 2. 為日後理解 Linux 核心特定運算加速機制做準備; ::: ==[作答表單](https://forms.gle/VsXYbVND5wv7hD2U8)== --- ### 測驗 `1` 考慮到整數 `PAGE_QUEUES` 可能有以下數值: * (1 or 2 or 3 or 4) * (5 or 6 or 7 or 8) $\times$ (2^n^), n from 1 to 14 給定 `size_t offset`,試著將原本運算: ```cpp #include <stdint.h> size_t blockidx = offset / PAGE_QUEUES; ``` 由於 `PAGE_QUEUES` 的數值分佈已知,在整數除法時,可思考加速運算的機制。需要注意,某些硬體平台缺乏整數除法指令 (如 Arm Cortex-A8),即使 Intel 公司出品的 Core 處裡器 [Sandy Bridge 微架構](https://en.wikipedia.org/wiki/Sandy_Bridge)中,針對 64 位元整數的除法運算,會佔用 40 到 103 個處理器週期,運算成本仍屬沈重。 > 來源: [Agner Fog’s instruction tables](https://www.agner.org/optimize/instruction_tables.pdf),第 180 頁 於是我們可預先進行計算,從而避免整數除法指令的使用: (假設在 x86_64 硬體執行 GNU/Linux 並透過 gcc/clang 編譯) ```cpp #include <stdint.h> #define ffs32(x) ((__builtin_ffs(x)) - 1) size_t blockidx; size_t divident = PAGE_QUEUES; blockidx = offset >> ffs32(divident); divident >>= ffs32(divident); switch (divident) { CASES } ``` 其中 `CASE` 可能形如: ```cpp case 2: blockidx /= 2; break; ``` 這樣的組合,請用最少的 case-break 敘述做出同等 `size_t blockidx = offset / PAGE_QUEUES;` 效果的程式碼。 參考資料: * [Integer division is slow](https://kristerw.blogspot.com/2017/05/integer-division-is-slow.html) ==作答區== CASE 至少該包含哪些數字: (複選) * `(a)` 2 * `(b)` 3 * `(c)` 4 * `(d)` 5 * `(e)` 6 * `(f)` 7 * `(g)` 8 * `(i)` 9 * `(j)` 10 :::success 延伸問題: 1. 解釋程式運算原理,可搭配 Microsoft Research 的專案 [snmalloc](https://github.com/microsoft/snmalloc) 來解說; * 對應的原始程式碼 [src/mem/sizeclass.h](https://github.com/microsoft/snmalloc/blob/master/src/mem/sizeclass.h#L54-L145) 2. 另一個記憶體管理器 [Hardened Malloc](https://www.whonix.org/wiki/Hardened_Malloc) 針對整數除法也有類似的加速機制,不過更加複雜,利用到 [third_party/libdivide.h](https://github.com/GrapheneOS/hardened_malloc/blob/master/third_party/libdivide.h),請解釋和上述手法相似的部分; 3. Linux 核心原始程式碼也有類似技巧,例如 [do_div(): generic optimization for constant divisor on 32-bit machines](https://lore.kernel.org/patchwork/patch/614225/),請搭配購新的 Linux 核心 (v5.5+) 來解說這類手法; :::
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.