web-dev-qa-db-ja.com

メモリ割り当ての時間計算量

New、mallocなどを使用した動的メモリ割り当ての時間計算量はどれくらいですか?メモリアロケータがどのように実装されているかについてはほとんど知りませんが、答えは実装に依存していると思います。したがって、より一般的なケース/実装のいくつかについて回答してください。

編集:最悪の場合、ヒープの割り当てに制限がないという話を漠然と覚えていますが、平均的/典型的な場合に本当に興味があります。

40
dsimcha

O表記を扱うときに理解しなければならないことの1つは、nが何であるかを理解することが非常に重要であることが多いということです。 nが制御可能なものに関連するものである場合(例:ソートするリスト内の要素の数)、一生懸命に見るのは理にかなっていますそれで。

ほとんどのヒープ実装では、nは、マネージャーが処理しているメモリの連続したチャンクの数です。これは明らかにnot通常はクライアントの制御下にあるものです。クライアントが実際に制御できる唯一のnは、必要なメモリのチャンクのサイズです。多くの場合、これはアロケータにかかる時間とは関係ありません。大きいnは、小さいnと同じくらい迅速に割り当てることができます。時間がかかる場合もあれば、サービスが提供できない場合もあります。これはすべて、他のクライアントからの以前の割り当てと割り当て解除の方法に応じて、同じnで変更される可能性があります。したがって、実際には、ヒープを実装していない限り、 正しい答えはそれが非決定論的であるということです

これが、ハードリアルタイムプログラマーが(起動後)動的割り当てを回避しようとする理由です。

28
T.E.D.

ヒープアロケータの時間計算量は、最適化する対象に応じて、システムごとに異なる可能性があります。

デスクトップシステムでは、ヒープアロケータは、最近の割り当てのキャッシュ、一般的な割り当てサイズのルックアサイドリスト、特定のサイズ特性を持つメモリチャンクのビンなど、さまざまな戦略を組み合わせて使用​​し、割り当て時間を短縮しながら断片化を管理しやすくします。使用されるさまざまな手法の概要については、Doug Leaのmalloc実装に関する注記を参照してください。 http://g.oswego.edu/dl/html/malloc.html

より単純なシステムの場合、リンクリストに格納されている空きブロックを使用して、ファーストフィットまたはベストフィットの戦略を使用できます(これにより、O(N)時間、Nは次の数になります)ただし、AVLツリーなどのより高度なストレージシステムを使用して、O(log N)時間で空きブロックを見つけることができる場合があります( http://www.oocities.org/wkaras/heapmm /heapmm.html )。

リアルタイムシステムは、TLSF(Two-Level Segregate Fit)のようなヒープアロケーターを使用する場合があります。これにはO(1)割り当てコスト: http://www.gii.upv .es/tlsf /

24
Michael Burr

たった2つの発言:

  • [〜#〜] tlsf [〜#〜] is O(1)は、単一のループがないという意味で、最大2Gbを管理します。信じがたいことです。コードを確認してください。

  • 「最適な」ポリシー(タイトなブロックを見つける)が小さな断片化を実現するのに最適であるというのは真実ではありません。この主張を実証することは簡単ではありません。実際、正式に証明されていませんが、その方向に進む証拠はたくさんあります。 (素敵な研究トピック)。

3
Ismael

一般的にはO(n)ここで、nは使用可能なメモリブロックの数です(適切なメモリブロックを見つけるには使用可能なメモリブロックをスキャンする必要があるため)。

そうは言っても、サイズ範囲に応じて使用可能なブロックの複数のリストを維持するなど、高速化できる最適化を見てきました(つまり、1k未満のブロックは1つのリストにあり、1kから10kのブロックは別のリストにあります)。 )。

これはまだO(n)ですが、nが小さいだけです。

無制限のヒープ割り当てがあることをソースに確認したいと思います(それによって、それが永遠にかかる可能性があることを意味する場合)。

2
paxdiablo

典型的なアロケータがどのように機能するかを確認してください。

バンプポインタアロケータはO(1)で機能し、それは小さな '1'です。

分離ストレージアロケータの場合、kバイトの割り当ては、「List(n)から最初のブロックを返す」ことを意味します。ここで、List(n)はnバイトのブロックのリストです。ここでn> = k。それ かもしれない List(n)が空であることがわかったため、次のリスト(List(2n))のブロックを、結果の両方のブロックで分割する必要がありますnバイトがList(n)に配置され、この効果might利用可能なすべてのサイズに波及し、O(ns )ここで、nsは使用可能なさまざまなサイズの数であり、ns = log(N)ここで[〜#〜] n [〜#〜]はサイズです利用可能な最大のブロックサイズの、それでも小さいでしょう。ほとんどの場合、特に多数のブロックが割り当てられ、割り当てが解除された後の複雑さはO(1)です。

2
doppelfish