3

N3485 20.6.9.1 [allocator.members]/1 言います:

ストレージの特定のユニットを割り当てまたは割り当て解除するこれらの関数の呼び出しは、1 つの合計順序で発生し、そのような割り当て解除呼び出しはそれぞれ、この順序で次の割り当て (存在する場合) の前に発生します。

この最後の要件は私を混乱させます。標準では、メモリのブロックを割り当て ( block と呼びましょうa)、別のブロックを割り当てた場合 ( block と呼びましょう)、 block の割り当てが解除されるまでbblock の割り当てを解除することは許可されていないようです。ab

vectorこれが実際にこの段落が意味するものである場合、スペース効率の良い方法で成長する のようなものを実装する方法がわかりません。これは、より大きなバッファーを割り当ててから、以前に割り当てられた (小さすぎる) バッファーの割り当てを解除することができなかったためです。

これは実際にこの段落が意味することですか、それともこのセクションを誤解していますか?

4

1 に答える 1

2

ストレージの特定のユニットを割り当てまたは割り当て解除するこれらの関数の呼び出しは、1 つの合計順序で発生し、そのような割り当て解除呼び出しはそれぞれ、この順序で次の割り当て (存在する場合) の前に発生します。

私には思えますが、割り当てと割り当て解除の間に事前発生関係を確立するだけです(おそらく、コンパイラの不適切な最適化から生じる同時実行の問題を防ぐためです)。abどこabが異なる割り当てられたリージョンであるかの関係を確立することは絶対にありません。

コンパイラは人間の論理ではなく、仕様に従うことに注意してください。仕様は、コンパイラー・プログラマーが注意する必要があるすべての詳細を記憶するのに役立ちます (仕様に従っていれば、それは正しいことです)。これが、仕様に明らかな詳細が含まれている理由です。詳細の 1 つは、割り当て解除/割り当てがメモリ バリアを構成することです。

比較

reads -> deallocation -> allocation -> writes

reads -> deallocation
allocation -> writes

発生前の関係がなければ、2 つのスレッドが同じメモリ領域 (ストレージの単位) を同時に使用する可能性があります (メモリ領域によって観察される)。先行発生関係では、割り当て解除スレッドからのすべてのアクセスは、割り当てスレッドが使用する前にフラッシュする必要があります。

于 2012-12-09T08:11:46.837 に答える