化)
一、從一次詭異的性能抖動說起去年在調(diào)一個分布式存儲的RDMA路徑時,遇到一個讓人抓狂的問題:單連接小IO(4KB)的延遲曲線,每隔幾十秒就會出現(xiàn)一個尖刺,峰值延遲從正常的5μs直接跳到200μs+。抓了ibv_devinfo、perftest、甚至用ftrace跟蹤內(nèi)核路徑,最后發(fā)現(xiàn)罪魁禍?zhǔn)拙谷皇荄oorbell的寫入時機。當(dāng)時代碼里每個WR(Work Request)提交后都立刻調(diào)用了ibv_post_send,然后緊跟著一個mmio寫Doorbell。這種寫法在低負(fù)載下完全沒問題,但一旦隊列深度(QD)超過16,Doorbell的MMIO寫入就成了PCIe總線上的“堵車點”——每次寫操作都要穿越PCIe拓?fù)?,而CPU側(cè)的寫合并(Write Combining)策略又和硬件期望的Doorbell語義打架,最終導(dǎo)致硬件側(cè)Doorbell丟失或延遲處理。這個坑讓我意識到:RDMA編程里,批量提交WR和Doorbell優(yōu)化不是“錦上添花”,而是“保命操作”。下面直接上干貨,不講虛的。二、WR批量提交:別讓硬件餓著2.1 單WR提交的代價每次ibv_post_send調(diào)用,本質(zhì)上是在軟件隊列(SQ)里插入一個WR,然后觸發(fā)一次Doorbell通知硬件“有活干了”。但這里有個隱藏成本:Doorbell的MMIO寫入大約需要幾百納秒到幾微秒(取決于PCIe拓?fù)浜虲PU頻率),而WR本身的構(gòu)造和鏈表操作可能只有幾十納秒。如果每個WR都單獨提交,Doorbell開銷會吃掉大部分性能。更坑的是,某些網(wǎng)卡(比如Mellanox ConnectX-