在儲存系統寫資料的過程中,出於效能上的考慮,新寫的資料並不是每次都flush到目標儲存中的,而是先放入到乙個buffer空間裡,等到buffer空間滿了,再做一次flush出去的動作。這種情況和人們等車的例子極為類似,一輛車等人都上滿了再開,才能保證更高的效率。但是這種緩衝設計模式還是存有乙個主要弊端的,當緩衝資料滿後將會阻塞住後面的資料操作直到緩衝資料完全flush出去。更簡單的來說,這裡會有個throughput的問題。那麼有什麼改進辦法呢,答案是利用另外乙個緩衝構成雙緩衝模式。本文筆者來聊聊雙緩衝的模式設計。
我們先來回顧下單緩衝的工作模式,工作原理上面已經提到過了,如下圖所示。
雙緩衝比較學術的稱謂叫做doublebuffer。這個有個大家可能理解的誤區:雙緩衝就是單緩衝在size空間上的的double。如果是這這種模式,throughput問題依然存在。
如果說增大緩衝區長度屬於縱向擴充套件的話,那麼這裡所說的雙緩衝則是橫向上的擴充套件。
它的運作原理如下:
將緩衝區分為2份,1份為當前緩衝區buf current,另外1份為預寫入分割槽buf ready,兩個緩衝區空間大小一致。current區負責當前的寫操作存放,當我們達到緩衝處罰條件時,執行一次雙緩衝的調換操作。然後由另外的程式執行ready區的flush操作。被交換變為空緩衝區的current區重新用於這的資料寫入。
以上的執行模式有以下2大優勢:
1)程式無需反覆進行建立新緩衝的操作
2)程式的寫請求不會被阻塞住,除非current緩衝區已經滿了同時ready緩衝區資料還沒有全部flush出去
在使用雙緩衝區模式時,因為緩衝區是可能存在concurrent使用的情況,所以這裡需要有thread safe的處理,以此保證每個操作是原子的更新。比如雙緩衝在swap的時候就不應該發生add緩衝的動作,再比如還應該有乙個執行緒可先性的變數來告訴程式,ready緩衝區是否已完全flush出去。
同樣地,筆者簡單構建了雙緩衝區的流程圖,如下所示:
雙緩衝設計在一些儲存系統中有所應用,大家可以閱讀相關系統**進行細節上的閱讀,比如hdfs裡的editsdoublebuffer類。
雙緩衝模式
定義緩衝類封裝緩衝 一段可改變的狀態。緩衝被增量的修改,外部 將修改視為單一的原子操作。類儲存下乙個緩衝和當前緩衝。從當前緩衝區讀取資料,將資料寫入下乙個緩衝區,當改變完成後,將當前緩衝區和下乙個緩衝區交換。使用場景 1.需要維護一些增量修改的狀態 2.修改到一半時,狀態可能會被外部請求 3.防止請...
遊戲程式設計模式 雙緩衝模式
我們先看乙個典型的例子,每個遊戲引擎都要處理的問題 渲染。當引擎渲染出使用者看到的世界時,在同一時間它只渲染一塊 遠處山峰 欺負的丘陵 樹木,這些輪流渲染 假如使用者也逐步的觀察視窗的渲染過程,那麼看到的將是破碎的世界。這是我們不能接受的,場景比如平滑快速的更新,每一幀必須被完整的顯示。如何解決這個...
關於對映模式和雙緩衝的一些細節
正常使用對映模式的話會是這樣 setmapmode hdc,mm anisotropic setviewportextex hdc,1,1,null setwindowextex hdc,1,1,null setviewportorgex hdc,rc.right 2,rc.bottom 2,nul...