簡體   English   中英

Heap針對(但不限於)單線程使用進行了優化

[英]Heap optimized for (but not limited to) single-threaded usage

我在我的一個項目中使用自定義堆實現。 它由兩個主要部分組成:

  1. 修復了大小塊堆。 即只分配特定大小的塊的堆。 它分配更大的內存塊(虛擬內存頁或來自另一個堆),然后將它們分成原子分配單元。

    它快速執行分配/釋放(在O(1)中)並且沒有內存使用開銷,沒有考慮外部堆強加的事情。

  2. 全球通用堆。 它由上面(固定尺寸)堆的桶組成。 WRT它選擇適當桶的請求分配大小,並通過它執行分配。

    由於整個應用程序(大量)是多線程的 - 全局堆在其操作期間鎖定適當的存儲桶。

    注意 :與傳統堆相比,此堆不僅要求分配大小,還要求釋放分配大小。 這允許在沒有搜索或額外的內存開銷的情況下識別適當的桶(例如在分配的塊之前保存塊大小)。 雖然不太方便,但在我的情況下這是好的。 此外,由於“桶配置”在編譯時是已知的(通過C ++模板voodoo實現) - 在編譯時確定適當的桶。

到目前為止,一切看起來(並且有效)。

最近我研究了一種能夠大量執行堆操作的算法,並且自然會受到堆性能的影響。 分析顯示其鎖定會對其性能產生很大影響。 也就是說,堆本身工作得非常快(典型的分配只涉及一些內存解除引用指令),但由於整個應用程序是多線程的 - 相應的存儲桶受到關鍵部分的保護,該部分依賴於互鎖指令,這些指令很多重。

我通過給這個算法提供了自己的專用堆來解決這個問題,這個堆不受關鍵部分的保護。 但這在代碼級別強加了幾個問題/限制。 例如,需要在堆棧深處傳遞上下文信息,無論堆可能在哪里。 也可以使用TLS來避免這種情況,但這可能會導致我在特定情況下重新進入時出現一些問題。

這讓我想知道:是否有一種已知的技術來優化堆(但不限於)單線程使用?

編輯:

特別感謝@Voo建議查看google的tcmalloc。

它似乎與我做的更多或更少(至少對於小對象)的工作類似。 但此外,他們通過維護每線程緩存來解決我所遇到的確切問題。

我也想過這個方向,但我想保持每線程 然后釋放從屬於另一個線程的堆分配的內存塊有點棘手:應該將其插入到一個鎖定隊列中,並且應該通知其他線程,並異步釋放掛起的分配。 異步釋放可能會導致問題:如果該線程由於某種原因而忙(例如執行積極的計算) - 實際上不會發生內存釋放。 此外,在多線程場景中,釋放的成本要高得多。

OTOH使用緩存的想法似乎更簡單,更有效。 我會嘗試解決它。

非常感謝。

PS:

事實上谷歌的tcmalloc很棒。 我相信它的實現與我所做的非常相似(至少是固定大小的部分)。

但是,要迂腐,有一件事我的堆優越。 根據文檔,tcmalloc大約1%的開銷(漸近),而我的開銷是0.0061%。 確切地說是4 / 64K。

:)

一種想法是為每個線程維護一個內存分配器。 從全局內存池為每個分配器預先分配相當大的內存塊。 設計算法以從相鄰的內存地址分配塊狀塊(稍后將詳細介紹)。

當給定線程的分配器內存不足時,它會從全局內存池中請求更多內存。 此操作需要鎖定,但發生頻率遠低於當前情況。 當給定線程的分配器釋放它的最后一個字節時,將該分配器的所有內存返回到全局內存池(假設線程終止)。

這種方法將比您當前的方法更早耗盡內存(可以為一個永遠不需要它的線程保留內存)。 問題的嚴重程度取決於應用程序的線程創建/生命周期/銷毀配置文件。 您可以以額外的復雜性為代價來緩解這種情況,例如通過引入給定線程的內存分配器內存不足的信號,並且全局池已用完,其他內存分配器可以通過釋放一些內存來響應。

該方案的一個優點是它將傾向於消除錯誤共享 ,因為給定線程的存儲器傾向於在連續的地址空間中分配。

另外,如果你還沒有讀過它,我建議IBM的內存管理文章給任何實現自己內存管理的人。

UPDATE

如果目標是為多線程環境優化非常快的內存分配(而不是學習如何自己完成),請查看備用內存分配器。 如果目標是學習,也許可以查看他們的源代碼。

閱讀關於slab allocator和vmem的Jeff Bonwicks經典論文可能是一個好主意。 最初的slab分配器聽起來有點像你在做什么。 雖然不是很多線程友好,但它可能會給你一些想法。

Slab分配器:對象緩存內核內存分配器

然后他用VMEM擴展了這個概念,這肯定會給你一些想法,因為它在多CPU環境中有非常好的行為。

雜志和Vmem:將平板分配器擴展到許多CPU和任意資源

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM