cache_aligned_allocator
[memory_allocation.cache_aligned_allocator]
cache_aligned_allocator
は、[allocator.requirements] ISO C++ セクションのアロケーター要件をモデル化するクラス・テンプレートです。
cache_aligned_allocator
は、フォールス・シェアリングを回避するため、キャッシュライン境界でメモリーを割り当てます。フォールス・シェアリングは、論理的に異なる項目が同じキャッシュラインを占有する場合に発生します。複数のスレッドが異なる項目に同時にアクセスすると、パフォーマンスが低下します。項目が論理的には別であっても、プロセッサーのハードウェアはそれらの項目が 1 つの場所を共有しているとプロセッサー間でキャッシュラインを転送しなければならないことがあります。最終的には、論理的に異なる項目が異なるキャッシュライン上にある場合よりも、多くのメモリー・トラフィックが発生することがあります。
しかし、キャッシュラインに割り当てる利点には、cache_aligned_allocator
が暗黙的にパディングを追加するため、このクラスはデフォルトのアロケーターの代替えには適しないことがあります。そのため、cache_aligned_allocator
を使用して多数の小さなオブジェクトを割り当てると、メモリー使用量が増加する可能性があります。
// <oneapi/tbb/cache_aligned_allocator.h> ヘッダーで定義
namespace oneapi {
namespace tbb {
template<typename T> class cache_aligned_allocator {
public:
using value_type = T;
using size_type = std::size_t;
using propagate_on_container_move_assignment = std::true_type;
using is_always_equal = std::true_type;
cache_aligned_allocator() = default;
template<typename U>
cache_aligned_allocator(const cache_aligned_allocator<U>&) noexcept;
T* allocate(size_type);
void deallocate(T*, size_type);
size_type max_size() const noexcept;
};
} // namespace tbb
} // namespace oneapi
メンバー関数
- T *allocate(size_type n)
キャッシュライン境界にアライメントされた
n * sizeof(T)
バイトのメモリー割り当てへのポインターを返します。境界配置のため割り当てにはパディングが含まれます。
- void deallocate(T *p, size_type n)
p
が指すメモリー割り当てを解除します。パディング割り当ても同様に解除します。ポインターp
がallocate(n)
メソッドの結果でない場合の動作は未定義です。メモリーがすでに割り当て解除されている場合の動作は未定義です。
- size_type max_size() const noexcept
キャッシュ・アライメントの制約付きで
allocate(n)
呼び出しが成功する可能性がある最大値n
を返します。
非メンバー関数
これらの関数は、2 つの cache_aligned_allocator
インスタンスの比較操作を提供します。
template<typename T, typename U>
bool operator==(const cache_aligned_allocator<T>&,
const cache_aligned_allocator<U>&) noexcept;
template<typename T, typename U>
bool operator!=(const cache_aligned_allocator<T>&,
const cache_aligned_allocator<U>&) noexcept;
これらの関数が cache_aligned_allocator
オブジェクトの二項演算式で使用できる限り、これらの関数が定義される名前空間を指定する必要はありません。例えば、実装では同じ未指定の名前空間でクラスと関数を定義し oneapi::tbb::cache_aligned_allocator
をタイプエイリアスとして定義できます。この場合、非メンバー関数には引数依存のルックアップによってのみ到達できます。