5

malloc()現在、Windows での実装を検討しています。しかし、私の研究では、私を困惑させるものに出くわしました。

まず、API レベルでは、Windows は主にHeapAlloc()とのVirtualAlloc()呼び出しを使用してメモリを割り当てることを知っています。ここから、Microsoft の実装malloc()(CRT に含まれているもの - C ランタイム) は、基本的にHeapAlloc()480 バイトを超えるブロックを呼び出しVirtualAlloc()、断片化を防ぐために、小さな割り当て用に割り当てられた特別な領域を管理することを収集します。

まあ、それはすべて良いことです。しかし、Microsoft の .NET よりも最大 125% 高速であると主張するmalloc()nedmallocなどmalloc、 .

これはすべて、いくつかのことを疑問に思います。

  1. HeapAlloc()小さなブロックだけを呼び出すことができないのはなぜですか? フラグメンテーションに関してパフォーマンスが低下していますか (たとえば、「ベスト フィット」ではなく「ファースト フィット」を実行するなど)?

    • 実際、さまざまな API 割り当て呼び出しの内部で何が起こっているかを知る方法はありますか? それはかなり役に立ちます。
  2. nedmallocMicrosoft よりもはるかに高速な理由は何mallocですか?

  3. HeapAlloc()上記のことから、 /は非常に遅いので、たまに呼び出して、割り当てられたメモリ自体を管理するVirtualAlloc()方がはるかに高速であるという印象を受けました。malloc()その仮定は本当ですか?それともmalloc()、断片化のために「ラッパー」が必要なだけですか? このようなシステム コールは高速であると考える人もいるでしょう。少なくとも、システム コールを効率的にするために何らかの工夫が必要であると考える人もいるでしょう。

    • 本当なら、なぜそうなのですか?
  4. malloc平均して、典型的な呼び出し (おそらく、すでに割り当てられているセグメントの数の関数)によって実行されるメモリの読み取り/書き込みの数 (桁違い) は? 私は直観的に、平均的なプログラムでは数十だと思いますが、そうですか?

4

2 に答える 2

5
  1. HeapAlloc の呼び出しは、クロスプラットフォームには聞こえません。MS は、必要に応じて実装を自由に変更できます。離れることを勧める。:)
  2. Loki ライブラリが「小さなオブジェクト アロケータ」で行うように、メモリ プールをより効果的に使用している可能性があります。
  3. 本質的に汎用的なヒープ割り当ては、どの実装でも常に低速です。アロケーターがより「特化」されているほど、より高速になります。これにより、メモリ プール (およびアプリケーションに固有の使用される割り当てサイズ) を扱うポイント #2 に戻ります。
  4. わからない。
于 2010-07-07T22:45:01.520 に答える
1

上記のことから、HeapAlloc()/VirtualAlloc() は非常に遅いため、malloc() がそれらをたまに呼び出すだけで、割り当てられたメモリ自体を管理する方がはるかに高速であるという印象を受けました。その仮定は本当ですか?

OS レベルのシステム コールは、プロセスのメモリ空間全体を管理するように設計および最適化されています。それらを使用して整数に4バイトを割り当てることは、実際には最適ではありません.ライブラリコードで小さな割り当てを管理し、OSがより大きな割り当てを最適化できるようにすることで、全体的なパフォーマンスとメモリ使用量が向上します. 少なくとも私が理解している限りでは。

于 2010-07-07T22:45:06.327 に答える