2020年5月17日日曜日

mimallocの評価

こちらで、大変に詳しく解析をされています。
https://qiita.com/methane/items/e88901b7392c10cee2c9
pythonのmalloc置き換え用度では、glibcに比べてよろしくない、という結果のようです。

私のエンジンは、数十バイト規模のメモリを大量に消費しますので、それをシミュレーションする意味で、以下のソースを書きました。(Visual Studio 2019 mimalloc-override-testから書き換えDebugビルド)

ここで、取得しているメモリは、9バイトから始まって、およそ2KBまで、メモリを1バイトづつインクメンタルに取得しています。それを1ブロックとして1000個取得します。理論上の取得メモリは、公差1の等差数列で計算でき、およそ2GBです。(きっちり詰めたときおよそ2GB消費します。)

int main() {

    mi_stats_reset();  // ignore earlier allocations
    mi_heap_t* heap = mi_heap_new(); 
    mi_heap_t* old = mi_heap_set_default(heap);
    for (auto i = 0;i < 1000;i++) {
        for (auto j = 0;j < 2000;j++) {
            char* p = new char[9+j];
        }
        
    }
    
  //  mi_heap_destroy(heap));
    mi_stats_print(NULL);
    return 0;
}
heap stats:     peak      total      freed       unit      count
normal   4:   501.9 kb   501.9 kb       0 b       32 b     16.0 k   not all freed!
normal   6:   752.9 kb   752.9 kb       0 b       48 b     16.0 k   not all freed!
normal   8:  1003.9 kb  1003.9 kb       0 b       64 b     16.0 k   not all freed!
normal   9:     1.2 mb     1.2 mb       0 b       80 b     16.0 k   not all freed!
normal  10:     1.4 mb     1.4 mb       0 b       96 b     16.0 k   not all freed!
normal  11:     1.7 mb     1.7 mb       0 b      112 b     16.0 k   not all freed!
normal  12:     1.9 mb     1.9 mb       0 b      128 b     16.0 k   not all freed!
normal  13:     4.8 mb     4.8 mb       0 b      160 b     32.0 k   not all freed!
normal  14:     5.8 mb     5.8 mb       0 b      192 b     32.0 k   not all freed!
normal  15:     6.8 mb     6.8 mb       0 b      224 b     32.0 k   not all freed!
normal  16:     7.8 mb     7.8 mb       0 b      256 b     32.0 k   not all freed!
normal  17:    19.5 mb    19.5 mb       0 b      320 b     64.0 k   not all freed!
normal  18:    23.4 mb    23.4 mb       0 b      384 b     64.0 k   not all freed!
normal  19:    27.3 mb    27.3 mb       0 b      448 b     64.0 k   not all freed!
normal  20:    31.2 mb    31.2 mb       0 b      512 b     64.0 k   not all freed!
normal  21:    78.1 mb    78.1 mb       0 b      640 b    128.0 k   not all freed!
normal  22:    93.7 mb    93.7 mb       0 b      768 b    128.0 k   not all freed!
normal  23:   109.3 mb   109.3 mb       0 b      896 b    128.0 k   not all freed!
normal  24:   125.0 mb   125.0 mb       0 b      1.0 kb   128.0 k   not all freed!
normal  25:   312.5 mb   312.5 mb       0 b      1.2 kb   256.0 k   not all freed!
normal  26:   375.0 mb   375.0 mb       0 b      1.5 kb   256.0 k   not all freed!
normal  27:   437.5 mb   437.5 mb       0 b      1.7 kb   256.0 k   not all freed!
normal  28:   437.5 mb   437.5 mb       0 b      2.0 kb   224.0 k   not all freed!
normal  30:     3.0 kb     3.0 kb       0 b      3.0 kb       1     not all freed!

heap stats:     peak      total      freed       unit      count
    normal:     2.0 gb     2.0 gb       0 b        1 b              not all freed!
      huge:       0 b        0 b        0 b        1 b              ok
     giant:       0 b        0 b        0 b        1 b              ok
     total:     2.0 gb     2.0 gb       0 b        1 b              not all freed!
malloc requested:          1.8 gb

  reserved:     2.0 gb     2.0 gb       0 b        1 b              not all freed!
 committed:     2.0 gb     2.0 gb       0 b        1 b              not all freed!
     reset:       0 b        0 b        0 b        1 b              ok
   touched:     2.0 gb     2.0 gb       0 b        1 b              not all freed!
  segments:     531        531          0                           not all freed!
-abandoned:       0          0          0                           ok
   -cached:       0          0          0                           ok
     pages:    33.3 k     33.3 k        0                           not all freed!
-abandoned:       0          0          0                           ok
 -extended:   590.2 k
 -noretire:       0
     mmaps:       8
   commits:     577
   threads:       0          0          0                           ok
  searches:     0.9 avg
numa nodes:       1
   elapsed:      16.793 s
   process: user: 15.984 s, system: 0.765 s, faults: 545698, reclaims: 0, rss: 2.0 gb, commit charge: 2.0 gb
 
当然のことながら、個別オブジェクトをdeleteしていないので、freeでないと言ってきます。
次に、コメントアウトしていた、mi_head_destroy(heap)をEnableしてみます。

すると、以下のように、良い感じになりました。9バイトから始めたのは、8バイトだと何故かフリーされなかったからです。(??)  とりあえず、良さそうなので、実装してみようかなと思います。
ドキュメントによれば、Windowsでは、古い実装にAddOnするだけで、new/malloc オーバライドすることが出来るそうです。Linuxへのポートも当然サポートされているので、前に示した要件がクリアされています。しかし、未だ枯れていないので、注意は必要です。(最新のビルドは数日前でした。)
 
int main() heap stats:     peak      total      freed       unit      count
normal   4:   501.9 kb   501.9 kb   501.9 kb      32 b     16.0 k   ok
normal   6:   752.9 kb   752.9 kb   752.9 kb      48 b     16.0 k   ok
normal   8:  1003.9 kb  1003.9 kb  1003.9 kb      64 b     16.0 k   ok
normal   9:     1.2 mb     1.2 mb     1.2 mb      80 b     16.0 k   ok
normal  10:     1.4 mb     1.4 mb     1.4 mb      96 b     16.0 k   ok
normal  11:     1.7 mb     1.7 mb     1.7 mb     112 b     16.0 k   ok
normal  12:     1.9 mb     1.9 mb     1.9 mb     128 b     16.0 k   ok
normal  13:     4.8 mb     4.8 mb     4.8 mb     160 b     32.0 k   ok
normal  14:     5.8 mb     5.8 mb     5.8 mb     192 b     32.0 k   ok
normal  15:     6.8 mb     6.8 mb     6.8 mb     224 b     32.0 k   ok
normal  16:     7.8 mb     7.8 mb     7.8 mb     256 b     32.0 k   ok
normal  17:    19.5 mb    19.5 mb    19.5 mb     320 b     64.0 k   ok
normal  18:    23.4 mb    23.4 mb    23.4 mb     384 b     64.0 k   ok
normal  19:    27.3 mb    27.3 mb    27.3 mb     448 b     64.0 k   ok
normal  20:    31.2 mb    31.2 mb    31.2 mb     512 b     64.0 k   ok
normal  21:    78.1 mb    78.1 mb    78.1 mb     640 b    128.0 k   ok
normal  22:    93.7 mb    93.7 mb    93.7 mb     768 b    128.0 k   ok
normal  23:   109.3 mb   109.3 mb   109.3 mb     896 b    128.0 k   ok
normal  24:   125.0 mb   125.0 mb   125.0 mb     1.0 kb   128.0 k   ok
normal  25:   312.5 mb   312.5 mb   312.5 mb     1.2 kb   256.0 k   ok
normal  26:   375.0 mb   375.0 mb   375.0 mb     1.5 kb   256.0 k   ok
normal  27:   437.5 mb   437.5 mb   437.5 mb     1.7 kb   256.0 k   ok
normal  28:   437.5 mb   437.5 mb   437.5 mb     2.0 kb   224.0 k   ok
normal  30:     3.0 kb     3.0 kb     3.0 kb     3.0 kb       1     ok

heap stats:     peak      total      freed       unit      count
    normal:     2.0 gb     2.0 gb     2.0 gb       1 b              ok
      huge:       0 b        0 b        0 b        1 b              ok
     giant:       0 b        0 b        0 b        1 b              ok
     total:     2.0 gb     2.0 gb     2.0 gb       1 b              ok
malloc requested:          1.8 gb

  reserved:     2.0 gb     2.0 gb       0 b        1 b              not all freed!
 committed:     2.0 gb     2.0 gb   196.5 mb       1 b              not all freed!
     reset:       0 b        0 b        0 b        1 b              ok
   touched:     2.0 gb     2.0 gb     2.0 gb       1 b              ok
  segments:     531        531        531                           ok
-abandoned:       0          0          0                           ok
   -cached:       0          0          0                           ok
     pages:    33.3 k     33.3 k     33.3 k                         not all freed!
-abandoned:       0          0          0                           ok
 -extended:   590.2 k
 -noretire:       1
     mmaps:       8
   commits:     577
   threads:       0          0          0                           ok
  searches:     0.9 avg
numa nodes:       1
   elapsed:      31.050 s
   process: user: 29.953 s, system: 0.765 s, faults: 545700, reclaims: 0, rss: 2.0 gb, commit charge: 2.0 gb

0 件のコメント:

コメントを投稿