--- tags: linux2024 --- # [2024q1](https://wiki.csie.ncku.edu.tw/linux/schedule) 第 18 週測驗題 :::info 目的: 檢驗學員對 bitwise operation 的認知 ::: ==[作答表單](https://docs.google.com/forms/d/e/1FAIpQLSfDf-9XtzFj9HoijJOaQAjcIe-rM2FIp4nXGftRcxF28VgxCw/viewform)== (針對 Linux 核心「實作」課程) ### 測驗 `1` 延伸〈[Linux 核心原始程式碼的整數除法](https://hackmd.io/@sysprog/linux-intdiv)〉和[第 7 週測驗 `2`](https://hackmd.io/@sysprog/linux2024-quiz7),[fastdiv](https://gist.github.com/jserv/22ca89155b028dddd9bccd1bae9a01e9) (部分程式碼遮蔽) 提出快速除法實作。以下是測試程式碼: ```c #include <assert.h> #include <stdio.h> #include "fastdiv.h" int main(int argc, char **argv) { const uint64_t MAX_NUM = 1 << 16; const uint64_t MAX_DIV = 1 << 14; for (uint64_t d = 1U; d < MAX_DIV; ++d) { div_t fd; /* general method */ fastdiv(&fd, d); /* divide-by-d */ const uint64_t mul = fd.mul, add = fd.add, shift = fd.shift; div_t fd2; /* bounded method optimization */ fastdiv_bounded(&fd2, d, MAX_DIV); /* divide-by-d */ const uint64_t mul2 = fd2.mul, add2 = fd2.add, shift2 = fd2.shift; assert(mul2 == 1U || add2 == 0U || shift2 == 0U); assert(add2 == 0U); for (uint64_t num = 0; num < MAX_NUM; ++num) { const uint64_t normal = num / d; const uint64_t general = (num * mul + add) >> shift; const uint64_t bounded = (num * mul2) >> shift2; assert(general == normal); assert(bounded == normal); } } } ``` 請補完程式碼,使 `assert` 巨集不會在執行時期觸發錯誤並運作符合預期。作答規範: * `AAAA`, `BBBB`, `CCCC`, `DDDD` 皆為整數 * 不該存在小括號 (即 `(` 和 `)`),以最精簡的形式書寫 :::success 延伸問題: 1. 解釋上述程式碼運作原理,設計實驗來比較除法和 `fastdiv` 的效率,並試圖解釋其行為 2. 以 jemalloc 為例,解說快速除法運算的應用場景。嘗試在 Linux 核心原始程式碼找出類似的技巧 3. [GCC Bug #89845](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89845) 提及針對整數除法的加速機制,參照到 [Faster Remainder by Direct Computation Applications to Compilers and Software Libraries](https://arxiv.org/pdf/1902.01961.pdf),嘗試解讀其手段並舉例說明 4. [libdivine](https://github.com/ridiculousfish/libdivide) 提供更進階的除法加速機制,嘗試解釋其原理 :::
×
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
.