舉出 Linux 核心原始程式碼裡頭 bit rotation 的案例並說明
首先在 Linux source code include/linux/bitops.h
可以看到關於 bitops 的實作
這邊以 8 bit 的實作舉例:
而在 /tools/testing/selftests/bpf/progs/test_jhash.h
的 __jhash_mix()
可以看到使用 rol32
將 a
, b
, c
三組數字進行混合,進而減少算出的 hash 值碰撞的機率。
x86_64 指令集具備 rotr 和 rotl 指令,上述 C 程式碼經過編譯器最佳化 (例如使用 gcc) 後,能否運用到這二個指令呢?
我認為有機會。但是應該只會發生在使用操作 32 位元或是 64 位元的資料時,因為指令集並不支援小於 32 位元以下數值的 rotate 指令。
不能只有「認為有機會」,證明!
我在 Intel-based Mac 上面使用 gcc 搭配 -O1
編譯以下的程式碼:
這邊不將 b
設定為常數是因為 gcc 會直接計算出最後 a 的數值而不會產生 rotate 的指令
經過反組譯可以發現在 0x100003f63
的位址有 rorl
指令的存在:
說明上述程式碼的運作原理
這段程式碼共可以分為兩個部分
power of 2 的翻譯是「2 的冪」,而非「冪次」
給定 alignment
的數值不是 2 的冪
如果不是 2 的冪,只要數值換成 alignment
的倍數即可,所以當 sz
是 alignment
的倍數時, (sz + mask) / alignment
== (sz + mask) / alignment
所以得到的即是本身;但是如果 sz
不是 alignment
的倍數時,就會算成大於 sz
且最接近的 alignment
的倍數。
給定 alignment
的數值是 2 的冪
這邊的做法其實與上述的作法類似,但是因為 2 的冪可以利用 mask 直接去除 sz % alignment
的部分,因此寫法就會變成
解釋上述程式碼輸出
-
字元數量的原理
因為 for 迴圈所使用的變數是區域變數,所以對於每個新 fork()
產生的執行緒而言,他們都需要印出 NNN
個 -
,而在執行過程中總共會產生出的執行緒共是 個
因此若假設迴圈總共執行 次的話, -
的個數就會是
而題目給定的 49152
根據上述的推論可以轉換成下列的形式
所以可知 NNN
即是 12
解釋上述程式碼運作原理
這段程式碼的作用就是以 proxy 作為兩個伺服器的中介人並進行資料互傳。
因此 proxy()
在做的就是利用 poll
監聽 target_fd
與 cl_fd
兩者,當其中一方要傳送資料的時候,就使用 splice 進行對傳。
linux2021