我正想要在高吞吐量C++服務器中使用最佳數據結構。數據結構將被用來存儲從幾個到幾百萬個對象的任何東西,並且不需要排序(儘管可以非常便宜地提供獨特的排序鍵)。要求是它可以支持高效的插入,理想情況下是O(1),中等效率的移除和高效的遍歷。它不需要支持查找操作(除了可能需要刪除)。並行數據結構設計
扭曲的是它在修改時必須是線程安全的,而其他線程正在枚舉數據結構。這意味着一個簡單的紅黑樹不起作用,因爲一個線程不能插入一個元素(並執行必要的樹旋轉),而不會搞亂其他線程持有的任何光標。
它是而不是可接受的使用讀/寫鎖,並推遲寫操作,直到所有的讀取器完成,因爲讀操作可能會很長壽。讀者是否可以看到插入是否可見,這並不重要。
內存佔用也很重要,而小顯然更好!
有什麼建議?
迴應評論:
感謝您的答案。
不,插入無法使現有的迭代器無效。迭代器可能會或可能不會看到新插入,但是他們必須看到插入沒有發生時他們會看到的所有內容。
需要刪除,但是由於更高級別的規則,我可以保證迭代器永遠不會停止在可刪除的項目上。
爲每個節點鎖定遊標會對性能產生太大的影響。一次可能有多個線程讀取,多個線程在鎖中使用的任何類型的內存熱點都會導致內存帶寬(正如我們發現的難題!)。即使是多線程調用InterlockedIncrement的讀者的簡單計數也無法順利進行擴展。
我同意鏈接列表可能是最好的方法。刪除是很少見的,因此爲支持O(1)刪除而支付內存處罰是很昂貴的,我們可以根據需要分別計算這些值,因爲刪除往往是批處理操作。
幸運的是,只要在改變頭指針之前在插入的節點中更新指針,插入到鏈表中並不需要對讀取器進行任何鎖定。
鎖複製解鎖的想法很有趣。所涉及的數據量太大,無法用作讀者的默認設置,但它可能會在作家與讀者碰撞時使用。讀/寫鎖可以保護整個結構,如果數據結構與讀卡器發生衝突,寫入操作會克隆數據結構。寫入比讀取要少得多。
可以插入無效現有的迭代器?如果是這樣,那會讓生活更輕鬆。你想支持刪除嗎?如果是這樣,當一個線程刪除正在被另一個線程讀取的項目時,預期的行爲是什麼? – 2008-11-04 16:05:58
你的目標是什麼?無鎖或免等待數據結構? – user 2013-06-26 04:48:22