contributed by < leewei05
>
查看電腦 CPU 核心數並保留第 12 個核心 isolcpus=11
。更改完設定、更新 grub
後重新開機。之後即可以透過 taskset -c 11 ./executable
來跑效能。
只針對 cpu3 做設定
參考 KYG-yaya573142 同學 的作法,把上述的命令整合成單一 script。
為了能夠透過 gnuplot 圖表分析效能,需要先把核心計算、傳送至 userspace 的時間寫入一個檔案。自我檢查列表有提到 printk - print a kernel message
,雖然可能會有效能上的問題,但尚未了解 sysfs
以前先透過 printk
來印出計算各個 fib_sequence()
結果的時間。閱讀 printk 以及 The high-resolution timer API 撰寫以下的程式:
一開始 ./client
的輸出都沒有印時間,但過了一陣子才想到 printk
是印 Linux 核心的訊息,不會直接在 userspace 輸出。接著,我執行 dmesg
命令,查看核心的輸出,果不其然有上述 prink
的結果:
原先 printk
的方式不利於取得函式的回傳時間,故改寫 fib_write
回傳 fib_sequence()
的執行時間。
為了要傳遞 Kernel 的計算結果至 user space,我們可以使用 copy_to_user
函式。
首先,需要先配置 Kernel space 的記憶體。因為我們要回傳的 fibonacci 數列結果很長,所以選擇用 vmalloc
來配置虛擬的連續記憶體空間。實作以下 k_to_u
函式:
並且額外實作一個 fib_basic
封裝相關參數:
參考 KYG-yaya573142 同學的做法,利用 clock_gettime
來取得 userspace 的執行時間。並且為了更方便產生 gnuplot 的圖,
參考 gnuplot 語法解說和示範,撰寫以下 script:
執行結果如下:
透過排除效能分析干擾的技巧獲得以下結果
首先修改 fib_basic
的 VLA warning。理論上我們只需要知道第 N 項的費氏數列,所以不需要定義 k+2 長度的陣列。初步的想法為定義一個長度為 3 的陣列:
實作程式碼
閱讀給定的 Fast doubling 網誌 並實作以下程式碼。實作想法為小於 2 的輸入直接回傳值,而大於 2 的 Fibonacci number 則是根據輸入的數值為偶數還是奇數做對應的公式計算。
透過 clz 硬體指令加速
Small String Optmization(SSO) 是一個處理字串的最佳化技巧。SSO 所解決的問題是可以減少 small-sized string 在建立時所動態配置的記憶體。透過 SSO,當應用程式建立的字串小於特定長度時,我們不會配置新的 heap memory 來存字串,而是直接使用 stack memory(buffer) 存字串。這個方法可以大量減少動態配置記憶體的成本並提昇執行時期的效能。
以下是為 gcc 的字串結構:
Small String Optmization 實作細節
分為 small string(0~15 bytes) 以及 large string(15~x bytes 需要動態配置 heap memory)。small string 的最後一個 byte 仿照 fbstring 的實作方式,存剩餘的空間以及 flag bit。
為了實現 f(500)
的運算,至少需要支援 107 個 bytes 包含 null terminator。為了方便計算直接設定字串長度上限為 256 個 bytes:
雜
\0
NULL terminator。延伸閱讀
Linux Kernel 在 fs.h 定義了 file_operations
介面(interface)。可以透過註冊不同的檔案來取得不同 Fibonacci 求值的實作。
參考 hsuedw 同學 的實作,首先在 client.c
定義檔案名稱:
f(92) = 7540113804746346429