多線程的記憶體 Clerkmt_alloc

來源:互聯網
上載者:User

A fixed-size, multi-thread optimized allocator

原文URL:http://list.cs.brown.edu/people/jwicks/libstdc++/html/ext/mt_allocator.html 簡介

mt allocator是一個固定大小(2的冪)記憶體的分配器,最初是為多線程應用程式(以下簡稱為MT程式)設計的。經過多年的改進,現在它在單線程應用程式(以下簡稱為ST程式)裡也有出色的表現了。

本文的目的是從應用程式的角度描述mt allocator的“內幕”。   總體設計

mt allocator有3個組成部分:描述記憶體池特徵的參數,把記憶體池關聯到通用或專用方案的policy類,和從policy類繼承來的實際的記憶體 Clerk類。

描述記憶體池特徵的參數是:

template<bool _Thread>

     class __pool

這個類表示是否支援線程,然後對多線程(bool==true)和單線程(bool==false)情況進行顯式特化。可以用定製的參數來替代這個類。

對於policy類,至少有2種不同的風格,每種都可以和上面不同的記憶體池參數單獨搭配:第一個策略,__common_pool_policy,實現了一個通用記憶體池,即使分配的物件類型不同,比如char和long,也使用同一個的記憶體池。這是預設的策略。 template < bool  _Thread >
     struct  __common_pool_policy

  template < typename _Tp,  bool  _Thread >
     struct  __per_type_pool_policy

 第二個策略,__per_type_pool_policy,對每個物件類型都實現了一個單獨的記憶體池,於是char和long會使用不同的記憶體池。這樣可以對某些類型進行單獨調整。

把上面這些放到一起,我們就得到了實際的記憶體 Clerk: template < typename _Tp, typename _Poolp  =  __default_policy >
     class  __mt_alloc :  public  __mt_alloc_base < _Tp > ,  _Poolp

這個類有標準庫要求的介面,比如allocate和deallocate函數等。  可調參數

有些配置參數可以修改,或調整。有一個嵌套類:包含了所有可調的參數,即: struct  __pool_base::_Tune

 

l  位元組對齊

l  多少位元組以上的記憶體直接用new分配

l  可分配的最小的記憶體塊大小

l  每次從OS申請的記憶體塊的大小

l  可支援的最多線程數目

l  單個線程能儲存的空閑塊的百分比(超過的空閑塊會歸還給全域空閑鏈表)

l  是否直接使用new和delete

對這些參數的調整必須在任何記憶體配置動作之前,即記憶體 Clerk初始化的時候,比如: 

#include  < ext / mt_allocator.h >

struct  pod
{
  int i;
  int j;
} ;

int  main()
{
  typedef pod value_type;
  typedef __gnu_cxx::__mt_alloc<value_type> allocator_type;
  typedef __gnu_cxx::__pool_base::_Tune tune_type;

  tune_type t_default;
  tune_type t_opt(16, 5120, 32, 5120, 20, 10, false);
  tune_type t_single(16, 5120, 32, 5120, 1, 10, false);

  tune_type t;
  t = allocator_type::_M_get_options();  
  allocator_type::_M_set_options(t_opt);
  t = allocator_type::_M_get_options();  

  allocator_type a;
  allocator_type::pointer p1 = a.allocate(128);
  allocator_type::pointer p2 = a.allocate(5128);

  a.deallocate(p1, 128);
  a.deallocate(p2, 5128);

  return 0;
}

初始化

靜態變數(記憶體鏈表的指標,控制參數等)的初始化為預設的值,比如:  template < typename _Tp >  size_t
__mt_alloc < _Tp > ::_S_freelist_headroom  =   10 ;

首次調用allocate()時,也會調用_S_init()函數。為了保證在MT程式裡它只被調用一次,我們使用了__gthread_once(參數是_S_once_mt和_S_init)函數;在ST程式裡則檢查靜態bool變數_S_initialized。

_S_init()函數:如果設定了GLIBCXX_FORCE_NEW環境變數,它會把_S_force_new設定成true,這樣allocate()就直接用new來申請記憶體,deallocate()用delete來釋放記憶體。

如果沒有設定GLIBCXX_FORCE_NEW,ST和MT程式都會:

1)計算bin的個數。bin是指2的指數位元組的記憶體集合。預設情況下,mt allocator只處理128位元組以內的小記憶體配置(或者通過在

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.