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 ✅