cache_aligned_allocator.h
Go to the documentation of this file.
/*
Copyright (c) 2005-2020 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef __TBB_cache_aligned_allocator_H
#define __TBB_cache_aligned_allocator_H
#include <new>
#include "tbb_stddef.h"
#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
#include <utility> // std::forward
#endif
#if __TBB_CPP17_MEMORY_RESOURCE_PRESENT
#include <memory_resource>
#endif
namespace tbb {
namespace internal {
size_t __TBB_EXPORTED_FUNC NFS_GetLineSize();
void* __TBB_EXPORTED_FUNC NFS_Allocate( size_t n_element, size_t element_size, void* hint );
void __TBB_EXPORTED_FUNC NFS_Free( void* );
}
#if _MSC_VER && !defined(__INTEL_COMPILER)
// Workaround for erroneous "unreferenced parameter" warning in method destroy.
#pragma warning (push)
#pragma warning (disable: 4100)
#endif
template<typename T>
class cache_aligned_allocator {
public:
typedef typename internal::allocator_type<T>::value_type value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
template<typename U> struct rebind {
typedef cache_aligned_allocator<U> other;
};
cache_aligned_allocator() throw() {}
cache_aligned_allocator( const cache_aligned_allocator& ) throw() {}
template<typename U> cache_aligned_allocator(const cache_aligned_allocator<U>&) throw() {}
pointer address(reference x) const {return &x;}
const_pointer address(const_reference x) const {return &x;}
pointer allocate( size_type n, const void* hint=0 ) {
// The "hint" argument is always ignored in NFS_Allocate thus const_cast shouldn't hurt
return pointer(internal::NFS_Allocate( n, sizeof(value_type), const_cast<void*>(hint) ));
}
void deallocate( pointer p, size_type ) {
internal::NFS_Free(p);
}
size_type max_size() const throw() {
return (~size_t(0)-internal::NFS_MaxLineSize)/sizeof(value_type);
}
#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
template<typename U, typename... Args>
void construct(U *p, Args&&... args)
{ ::new((void *)p) U(std::forward<Args>(args)...); }
#else // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
#if __TBB_CPP11_RVALUE_REF_PRESENT
void construct( pointer p, value_type&& value ) {::new((void*)(p)) value_type(std::move(value));}
#endif
void construct( pointer p, const value_type& value ) {::new((void*)(p)) value_type(value);}
#endif // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
void destroy( pointer p ) {p->~value_type();}
};
#if _MSC_VER && !defined(__INTEL_COMPILER)
#pragma warning (pop)
#endif // warning 4100 is back
template<>
class cache_aligned_allocator<void> {
public:
typedef void* pointer;
typedef const void* const_pointer;
typedef void value_type;
template<typename U> struct rebind {
typedef cache_aligned_allocator<U> other;
};
};
template<typename T, typename U>
inline bool operator==( const cache_aligned_allocator<T>&, const cache_aligned_allocator<U>& ) {return true;}
template<typename T, typename U>
inline bool operator!=( const cache_aligned_allocator<T>&, const cache_aligned_allocator<U>& ) {return false;}
#if __TBB_CPP17_MEMORY_RESOURCE_PRESENT
class cache_aligned_resource : public std::pmr::memory_resource {
public:
cache_aligned_resource() : cache_aligned_resource(std::pmr::get_default_resource()) {}
explicit cache_aligned_resource(std::pmr::memory_resource* upstream) : m_upstream(upstream) {}
std::pmr::memory_resource* upstream_resource() const {
return m_upstream;
}
private:
void* do_allocate(size_t bytes, size_t alignment) override {
size_t cache_line_alignment = correct_alignment(alignment);
uintptr_t base = (uintptr_t)m_upstream->allocate(correct_size(bytes) + cache_line_alignment);
__TBB_ASSERT(base != 0, "Upstream resource returned NULL.");
#if _MSC_VER && !defined(__INTEL_COMPILER)
// unary minus operator applied to unsigned type, result still unsigned
#pragma warning(push)
#pragma warning(disable: 4146 4706)
#endif
// Round up to the next cache line (align the base address)
uintptr_t result = (base + cache_line_alignment) & -cache_line_alignment;
#if _MSC_VER && !defined(__INTEL_COMPILER)
#pragma warning(pop)
#endif
// Record where block actually starts.
((uintptr_t*)result)[-1] = base;
return (void*)result;
}
void do_deallocate(void* ptr, size_t bytes, size_t alignment) override {
if (ptr) {
// Recover where block actually starts
uintptr_t base = ((uintptr_t*)ptr)[-1];
m_upstream->deallocate((void*)base, correct_size(bytes) + correct_alignment(alignment));
}
}
bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override {
if (this == &other) { return true; }
#if __TBB_USE_OPTIONAL_RTTI
const cache_aligned_resource* other_res = dynamic_cast<const cache_aligned_resource*>(&other);
return other_res && (this->upstream_resource() == other_res->upstream_resource());
#else
return false;
#endif
}
size_t correct_alignment(size_t alignment) {
__TBB_ASSERT(tbb::internal::is_power_of_two(alignment), "Alignment is not a power of 2");
#if __TBB_CPP17_HW_INTERFERENCE_SIZE_PRESENT
size_t cache_line_size = std::hardware_destructive_interference_size;
#else
size_t cache_line_size = internal::NFS_GetLineSize();
#endif
return alignment < cache_line_size ? cache_line_size : alignment;
}
size_t correct_size(size_t bytes) {
// To handle the case, when small size requested. There could be not
// enough space to store the original pointer.
return bytes < sizeof(uintptr_t) ? sizeof(uintptr_t) : bytes;
}
std::pmr::memory_resource* m_upstream;
};
#endif /* __TBB_CPP17_MEMORY_RESOURCE_PRESENT */
} // namespace tbb
#endif /* __TBB_cache_aligned_allocator_H */
tbb::cache_aligned_allocator::value_type
internal::allocator_type< T >::value_type value_type
Definition: cache_aligned_allocator.h:62
internal
Definition: _flow_graph_async_msg_impl.h:24
tbb::cache_aligned_allocator::const_pointer
const typedef value_type * const_pointer
Definition: cache_aligned_allocator.h:64
void
void
Definition: ittnotify_static.h:91
tbb::cache_aligned_allocator::size_type
size_t size_type
Definition: cache_aligned_allocator.h:67
tbb::cache_aligned_allocator< void >::rebind::other
cache_aligned_allocator< U > other
Definition: cache_aligned_allocator.h:124
tbb::cache_aligned_allocator< void >::value_type
void value_type
Definition: cache_aligned_allocator.h:122
__TBB_ASSERT
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:165
tbb::cache_aligned_allocator::allocate
pointer allocate(size_type n, const void *hint=0)
Allocate space for n objects, starting on a cache/sector line.
Definition: cache_aligned_allocator.h:80
tbb::cache_aligned_allocator< void >::pointer
void * pointer
Definition: cache_aligned_allocator.h:120
tbb::interface7::internal::cache_line_size
static const size_t cache_line_size
Definition: _mutex_padding.h:28
tbb::cache_aligned_allocator::deallocate
void deallocate(pointer p, size_type)
Free block of memory that starts on a cache line.
Definition: cache_aligned_allocator.h:86
tbb
The graph class.
Definition: serial/tbb/parallel_for.h:46
tbb::cache_aligned_allocator::address
pointer address(reference x) const
Definition: cache_aligned_allocator.h:76
tbb::cache_aligned_allocator::address
const_pointer address(const_reference x) const
Definition: cache_aligned_allocator.h:77
tbb::operator!=
bool operator!=(const cache_aligned_allocator< T > &, const cache_aligned_allocator< U > &)
Definition: cache_aligned_allocator.h:132
tbb::cache_aligned_allocator
Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5.
Definition: cache_aligned_allocator.h:60
tbb::cache_aligned_allocator::rebind::other
cache_aligned_allocator< U > other
Definition: cache_aligned_allocator.h:70
tbb::internal::is_power_of_two
bool is_power_of_two(integer_type arg)
A function to check if passed integer is a power of 2.
Definition: tbb_stddef.h:376
tbb::cache_aligned_allocator::const_reference
const typedef value_type & const_reference
Definition: cache_aligned_allocator.h:66
tbb::cache_aligned_allocator::reference
value_type & reference
Definition: cache_aligned_allocator.h:65
tbb::cache_aligned_allocator::cache_aligned_allocator
cache_aligned_allocator(const cache_aligned_allocator &)
Definition: cache_aligned_allocator.h:73
tbb::operator==
bool operator==(const cache_aligned_allocator< T > &, const cache_aligned_allocator< U > &)
Definition: cache_aligned_allocator.h:129
tbb::move
void move(tbb_thread &t1, tbb_thread &t2)
Definition: tbb_thread.h:319
tbb::internal::NFS_MaxLineSize
const size_t NFS_MaxLineSize
Compile-time constant that is upper bound on cache line/sector size.
Definition: tbb_stddef.h:216
tbb::cache_aligned_allocator::cache_aligned_allocator
cache_aligned_allocator(const cache_aligned_allocator< U > &)
Definition: cache_aligned_allocator.h:74
__TBB_EXPORTED_FUNC
#define __TBB_EXPORTED_FUNC
Definition: scalable_allocator.h:38
tbb::cache_aligned_allocator::construct
void construct(U *p, Args &&... args)
Copy-construct value at location pointed to by p.
Definition: cache_aligned_allocator.h:98
tbb::cache_aligned_allocator::pointer
value_type * pointer
Definition: cache_aligned_allocator.h:63
tbb::cache_aligned_allocator::max_size
size_type max_size() const
Largest value for which method allocate might succeed.
Definition: cache_aligned_allocator.h:91
tbb::cache_aligned_allocator::cache_aligned_allocator
cache_aligned_allocator()
Definition: cache_aligned_allocator.h:72
tbb::internal::NFS_GetLineSize
size_t __TBB_EXPORTED_FUNC NFS_GetLineSize()
Cache/sector line size.
Definition: cache_aligned_allocator.cpp:167
tbb::cache_aligned_allocator::rebind
Definition: cache_aligned_allocator.h:69
value
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long value
Definition: ittnotify_static.h:192
tbb::cache_aligned_allocator< void >::const_pointer
const typedef void * const_pointer
Definition: cache_aligned_allocator.h:121
tbb::cache_aligned_allocator::destroy
void destroy(pointer p)
Destroy value at location pointed to by p.
Definition: cache_aligned_allocator.h:108
tbb_stddef.h
tbb::cache_aligned_allocator::difference_type
ptrdiff_t difference_type
Definition: cache_aligned_allocator.h:68
p
void const char const char int ITT_FORMAT __itt_group_sync p
Definition: ittnotify_static.h:91
tbb::internal::NFS_Free
void __TBB_EXPORTED_FUNC NFS_Free(void *)
Free memory allocated by NFS_Allocate.
Definition: cache_aligned_allocator.cpp:198
tbb::internal::allocator_type::value_type
T value_type
Definition: tbb_stddef.h:472
tbb::internal::NFS_Allocate
void *__TBB_EXPORTED_FUNC NFS_Allocate(size_t n_element, size_t element_size, void *hint)
Allocate memory on cache/sector line boundary.
Definition: cache_aligned_allocator.cpp:176

Copyright © 2005-2020 Intel Corporation. All Rights Reserved.

Intel, Pentium, Intel Xeon, Itanium, Intel XScale and VTune are registered trademarks or trademarks of Intel Corporation or its subsidiaries in the United States and other countries.

* Other names and brands may be claimed as the property of others.