namespace std::pmr {
class synchronized_pool_resource;
class unsynchronized_pool_resource;
}
概要
pool_resourceは幾つかのブロックサイズ毎のメモリプールを管理し、要求サイズ毎に最適なプールからメモリを割り当てるmemory_resource実装である。
メモリ割り当て要求に内部のメモリプールから応えられない場合(最大のブロックサイズを超える要求があった場合)は、上流のメモリリソースからメモリを割り当てる。ほとんどの場合、上流メモリリソースへの割り当て要求は内部プールへの割り当て要求よりも少ない。
以下2つのpool_resourceが提供される。
pool_resourceクラス名 |
説明 | 対応バージョン |
|---|---|---|
synchronized_pool_resource |
スレッドセーフなpool_resource |
C++17 |
unsynchronized_pool_resource |
スレッドセーフでないpool_resource |
C++17 |
synchronized_pool_resourceは外部同期機構無しで複数のスレッドからスレッドセーフにアクセスできる。
実装によっては同期コストの削減のためにスレッド毎にメモリプールを持つ可能性がある。
unsynchronized_pool_resourceは複数スレッドからアクセスした際にスレッドセーフ性が保証されないが、シングルスレッドで使用する場合に同期のためのオーバーヘッドを避けることができる。
pool_resourceの性質
- 内部管理メモリ領域は様々なブロックサイズのメモリプールに分かれている。
- それぞれのブロックサイズ毎のメモリプールは幾つかのチャンクの集まりであり、各チャンクは均一なサイズ(ブロックサイズ)のブロックに順番に分割されている。
do_allocateによって返されるメモリはブロック単位で割り当てられる。do_allocate(bytes, alignment)は、bytes以上で最小のブロックサイズのプールからメモリを割り当てる。bytesが最大ブロックサイズを超える場合、上流メモリリソースから直接割り当てられる。
- あるプールが枯渇した場合、次の
do_allocate時に上流メモリリソースからチャンク単位でプールを補充する。- 補充の度に補充されるチャンクサイズは等比数列に従って増加する(上限有)。
- 一定のチャンク毎に補充を行うことで連続した割り当てにおける参照局所性を高める狙いがある。
- 最大チャンクサイズ及び最大ブロックサイズは
pool_options構造体をコンストラクタに渡して調整可能。max_blocks_per_chunk: チャンクサイズの上限値、この値よりは大きくならないlargest_required_pool_block: ブロックサイズの最大値、この値を超える割り当て要求は上流メモリリソースから直接割り当てる
- 管理メモリの解放時は
deallocateが呼び出されていない領域があっても全てのメモリを解放する。
メンバ関数
構築・破棄
| 名前 | 説明 | 対応バージョン |
|---|---|---|
(constructor) |
コンストラクタ | C++17 |
(destructor) |
デストラクタ | C++17 |
operator=(const pool_resource&) = delete; |
コピー代入演算子(コピー禁止) | C++17 |
クラス名をpool_resourceとしているのは説明のためのプレースホルダで、synchronized_pool_resourceとunsynchronized_pool_resourceで共通ということである。
共通メンバ関数
| 名前 | 説明 | 対応バージョン |
|---|---|---|
release |
割り当てられている全てのメモリを解放する | C++17 |
upstream_resource |
利用している上流memory_resourceを取得する |
C++17 |
options |
適用されているプール設定をpool_optionsとして取得する |
C++17 |
非仮想インターフェース(NVI)
| 名前 | 説明 | 対応バージョン |
|---|---|---|
allocate |
メモリを確保する | C++17 |
deallocate |
メモリを解放する | C++17 |
is_equal |
オブジェクトを超えてメモリ領域の解放を行えるかを調べる | C++17 |
protected オーバーライド関数
| 名前 | 説明 | 対応バージョン |
|---|---|---|
do_allocate |
メモリを確保する | C++17 |
do_deallocate |
メモリを解放する | C++17 |
do_is_equal |
オブジェクトを超えてメモリ領域の解放を行えるかを調べる | C++17 |
非メンバ関数
| 名前 | 説明 | 対応バージョン |
|---|---|---|
operator== |
等値比較 | C++17 |
operator!= |
非等値比較 | C++17 |
synchronized_pool_resourceの処理系毎の実装
MSVC 2017, 2019
unsynchronized_pool_resourceを継承し、アクセスをmutexで同期させている。
スレッド毎にプールを持たない。
GCC 9.1
スレッド毎にプールを持ち、各プールはリンクリストで管理されている。
バージョン
言語
- C++17
処理系
- Clang: ??
- GCC: 9.1 ✅
- Visual C++: 2017 update 6 ✅