無(wú)鎖ring-buffer實(shí)現(xiàn)原理

linux 2.6.28推出了一種通用的ring-buffer實(shí)現(xiàn)觅够,但某些操作這種實(shí)現(xiàn)過(guò)多依賴鎖機(jī)制,導(dǎo)致性能不佳骡苞。目前DPDK使用的ring是基于Steven Rostedt提出的一種無(wú)鎖ring-buffer算法實(shí)現(xiàn)垂蜗,該算法消除了寫入時(shí)鎖依賴坑赡,為內(nèi)核的采集信息功能提供了快路徑,非常高效么抗。我們一起通過(guò)這篇文章學(xué)習(xí)下該算法的實(shí)現(xiàn)原理。

通用算法在linux上的使用如下:采集信息的功能由內(nèi)核來(lái)完成亚铁,因此需要存儲(chǔ)過(guò)程(寫操作)盡可能的耗時(shí)小蝇刀,保證對(duì)處理events的影響盡可能小。讀數(shù)據(jù)都是基于用戶空間完成徘溢,因此對(duì)性能要求相對(duì)低些吞琐。linux內(nèi)核提供的ring-buffer創(chuàng)建了一個(gè)環(huán)形、雙向頁(yè)面列表然爆,包括一個(gè)頭指針和尾指針站粟,寫基于尾指針,讀基于頭指針曾雕。當(dāng)ring-buffer寫滿時(shí)奴烙,有可能writers會(huì)覆蓋頭指針指向的頁(yè)面內(nèi)容,這將會(huì)導(dǎo)致讀操作數(shù)據(jù)異常剖张∏芯鳎基于上述原因,該算法提供一個(gè)獨(dú)立的reader頁(yè)面搔弄,該頁(yè)面完全獨(dú)立于雙向鏈表幅虑,這樣readers就不用擔(dān)心讀數(shù)據(jù)時(shí)會(huì)被writers將數(shù)據(jù)破壞。這種實(shí)現(xiàn)唯一的缺點(diǎn)是當(dāng)一個(gè)reader頁(yè)面處理完需要從鏈表中重新load一個(gè)頁(yè)面時(shí)顾犹,必須要將處理完的空page插到尾指針之后倒庵,同時(shí)將當(dāng)前的head page移除掉作為新的reader page,并將head page在鏈表上向前移動(dòng)炫刷,這個(gè)過(guò)程需要依賴鎖來(lái)保證安全擎宝。

Rostedt的算法中提出的ring-buffer結(jié)構(gòu)如下圖,H代表Header-flagged pointer:

ring-buffer結(jié)構(gòu)示意

當(dāng)存在多個(gè)writer時(shí)柬唯,writer A可以被其他的writer B打斷认臊,只要A能保證在B開始前完成其寫入動(dòng)作。該功能可有一種稱為interrupts stack機(jī)制來(lái)實(shí)現(xiàn)锄奢,當(dāng)一個(gè)wirter初始化時(shí)失晴,在尾指針之后預(yù)留空間來(lái)處理寫入事件,當(dāng)完成時(shí)更新尾指針位置拘央,同時(shí)引入另一個(gè)指針commit指針涂屁,用來(lái)標(biāo)記 最近的寫入完成指針。在一個(gè)空的ring-buffer中灰伟,reader page\tail page\commit page有可能指向同一處拆又。

為了消除寫過(guò)程的鎖依賴儒旬,提出了 cmpxchg() 原子操作如下:

    R = cmpxchg(A, C, B) 
        - Assign A = B if A == C
        - Return A at the time of the call, unconditionally

算法還假設(shè)雙向鏈表的指針是4字節(jié)對(duì)齊,預(yù)留低2bit給flags:
-HEADER --- 指針指向當(dāng)前的head page
-UPDATE --- 指針指向的page正在被寫入數(shù)據(jù)帖族,或者栈源,即將被設(shè)為head page

當(dāng)reader page消費(fèi)完成時(shí),當(dāng)前的head page需要從ring-buffer中脫落下來(lái)變成新的reader page竖般。通過(guò)在next指針中使用HEADER bit甚垦,readers可以使用cmxchg()來(lái)要求HEADER flag被標(biāo)記,保證頁(yè)面內(nèi)容未被修改過(guò)涣雕。當(dāng)writers將flag設(shè)置為UPDATE或者清除時(shí)艰亮,表示該頁(yè)面內(nèi)容已被修改過(guò),cmxchg()比較失敗挣郭,這樣reader會(huì)重新查找一個(gè)新的head page迄埃,從而避免使用鎖。
當(dāng)writers更新一個(gè)新的tail page時(shí)兑障,需要檢查next 指針的HEADER flag侄非。如果被設(shè)置,需要更新為UPDATE流译,表示該頁(yè)面正在被writers使用彩库,并會(huì)導(dǎo)致cmpxchg()檢查失敗,需要?jiǎng)冸x一個(gè)新的head page為reader page先蒋。這種狀態(tài)也意味著環(huán)接近寫滿狀態(tài)骇钦,僅剩一個(gè)頁(yè)面用來(lái)寫數(shù)據(jù)。

參考文獻(xiàn):

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末竞漾,一起剝皮案震驚了整個(gè)濱河市眯搭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌业岁,老刑警劉巖鳞仙,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異笔时,居然都是意外死亡棍好,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門允耿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)借笙,“玉大人,你說(shuō)我怎么就攤上這事较锡∫导冢” “怎么了?”我有些...
    開封第一講書人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵蚂蕴,是天一觀的道長(zhǎng)低散。 經(jīng)常有香客問(wèn)我俯邓,道長(zhǎng),這世上最難降的妖魔是什么熔号? 我笑而不...
    開封第一講書人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任稽鞭,我火速辦了婚禮,結(jié)果婚禮上引镊,老公的妹妹穿的比我還像新娘川慌。我一直安慰自己,他們只是感情好祠乃,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著兑燥,像睡著了一般亮瓷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上降瞳,一...
    開封第一講書人閱讀 51,258評(píng)論 1 300
  • 那天嘱支,我揣著相機(jī)與錄音,去河邊找鬼挣饥。 笑死除师,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的扔枫。 我是一名探鬼主播汛聚,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼短荐!你這毒婦竟也來(lái)了倚舀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤忍宋,失蹤者是張志新(化名)和其女友劉穎痕貌,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體糠排,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡舵稠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了入宦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哺徊。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖乾闰,靈堂內(nèi)的尸體忽然破棺而出唉工,到底是詐尸還是另有隱情,我是刑警寧澤汹忠,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布淋硝,位于F島的核電站雹熬,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏谣膳。R本人自食惡果不足惜竿报,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望继谚。 院中可真熱鬧烈菌,春花似錦、人聲如沸花履。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)诡壁。三九已至济瓢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間妹卿,已是汗流浹背旺矾。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留夺克,地道東北人箕宙。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像铺纽,于是被迫代替她去往敵國(guó)和親柬帕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • android 為了高效的 IPC 通信做了很多工作狡门,內(nèi)存管理就屬于其中之一雕崩。傳統(tǒng)的 IPC 傳遞數(shù)據(jù),至少需要2...
    zjfclimin閱讀 4,047評(píng)論 0 4
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,095評(píng)論 25 707
  • Disruptor提供了一種線程之間信息交換的方式融撞。 鎖的缺點(diǎn) 并發(fā)的問(wèn)題 想象有兩個(gè)線程嘗試修改同一個(gè)變量val...
    jiangmo閱讀 1,686評(píng)論 0 2
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)盼铁、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,098評(píng)論 4 62
  • 整本書最為溫暖的部分應(yīng)該就是關(guān)于她的后園吧,她跟祖父整日的玩鬧致扯,無(wú)憂無(wú)慮的生活肤寝,以后想起大概也會(huì)心里一暖吧。每...
    小胖子Carol閱讀 754評(píng)論 0 1