深入理解SPDK之八:性能優化

根筆者最近在SPDK優化上的工作,下面總結了一些可以提升性能的優化點。

永遠保持高隊列深度

對於NVME SSD和RDMA這種基於completion queue/submittion queue 硬件機制的設備,就應該根據硬件隊列執行的特性,始終保持隊列中有物理隊列深度這麼多的請求在跑,這樣纔可能榨乾硬件性能。

數據結構

在IO路徑上如果你需要緩存一段請求,並且只只需要操作它的頭和尾。如果是基於C++ 模板,切記:不要使用雙向鏈表,而應該用queue。

內存拷貝

大廠的很多基礎庫中,期望的淺複製,在有些情況下可能包括拷貝操作,針對這個需要仔細篩查。特別是在IO路徑上不同的函數參數傳遞
的過程中,儘量用指針傳遞。

內存分配

IO路徑上頻繁的內存分配會影響性能,特別是對 spdk 提供的內存分配函數。一種思路是預估請求的多少,預先分配好。

佔時高的函數

讀寫程序跑起來的時候,可以用perf 跟蹤並記錄到熱點函數,然後分析
是否符合預期,對於不符合預期的想辦法把它的時間佔比降下來。筆者通過perf 發現,對一個std::map結構進行判空比較佔據了超過5%的比例,後來通過把這個判斷放到其他條件之後,性能得到一定改善。

IO路徑上儘量避免鎖,因爲:
對於自旋鎖:它很耗CPU;對於互斥鎖:它又很可能導致頻繁的上下文切換。進而整體上影響性能。

去掉不必要的打印、睡眠、乘法、除法

把IO路徑上乘、除、模等需要比較多CPU週期的操作,改造成位的操作;把冗餘的日誌和睡眠減少乃至都去掉,也會對性能有提升。

內連函數、編譯選項 -O 優化、熱點函數彙編、使用高級指令

這個是常見的公共的優化方法,常見於計算密集型的應用。

通過綜合上面的措施,筆者把4K粒度的讀寫從2~3萬IOS優化到45萬左右IOPS。當然在多個線程併發、隊列深度不同的情況下,是否還能保持如此高的性能還有待驗證。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章