使std :: vector分配alignment的内存

是否有可能使std::vector自定义结构的std::vector分配alignment内存进一步处理与SIMD指令? 如果可以使用Allocator ,有没有人碰巧有这样一个分配器,他可以分享?

编辑:我删除了由GManNickGbuild议的std::allocator的inheritance,并使alignment参数编译时的事情。

我最近写了这段代码。 它没有testing,因为我喜欢它,所以继续并报告错误。 🙂

 enum class Alignment : size_t { Normal = sizeof(void*), SSE = 16, AVX = 32, }; namespace detail { void* allocate_aligned_memory(size_t align, size_t size); void deallocate_aligned_memory(void* ptr) noexcept; } template <typename T, Alignment Align = Alignment::AVX> class AlignedAllocator; template <Alignment Align> class AlignedAllocator<void, Align> { public: typedef void* pointer; typedef const void* const_pointer; typedef void value_type; template <class U> struct rebind { typedef AlignedAllocator<U, Align> other; }; }; template <typename T, Alignment Align> class AlignedAllocator { public: typedef T value_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef std::true_type propagate_on_container_move_assignment; template <class U> struct rebind { typedef AlignedAllocator<U, Align> other; }; public: AlignedAllocator() noexcept {} template <class U> AlignedAllocator(const AlignedAllocator<U, Align>&) noexcept {} size_type max_size() const noexcept { return (size_type(~0) - size_type(Align)) / sizeof(T); } pointer address(reference x) const noexcept { return std::addressof(x); } const_pointer address(const_reference x) const noexcept { return std::addressof(x); } pointer allocate(size_type n, typename AlignedAllocator<void, Align>::const_pointer = 0) { const size_type alignment = static_cast<size_type>( Align ); void* ptr = detail::allocate_aligned_memory(alignment , n * sizeof(T)); if (ptr == nullptr) { throw std::bad_alloc(); } return reinterpret_cast<pointer>(ptr); } void deallocate(pointer p, size_type) noexcept { return detail::deallocate_aligned_memory(p); } template <class U, class ...Args> void construct(U* p, Args&&... args) { ::new(reinterpret_cast<void*>(p)) U(std::forward<Args>(args)...); } void destroy(pointer p) { p->~T(); } }; template <typename T, Alignment Align> class AlignedAllocator<const T, Align> { public: typedef T value_type; typedef const T* pointer; typedef const T* const_pointer; typedef const T& reference; typedef const T& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef std::true_type propagate_on_container_move_assignment; template <class U> struct rebind { typedef AlignedAllocator<U, Align> other; }; public: AlignedAllocator() noexcept {} template <class U> AlignedAllocator(const AlignedAllocator<U, Align>&) noexcept {} size_type max_size() const noexcept { return (size_type(~0) - size_type(Align)) / sizeof(T); } const_pointer address(const_reference x) const noexcept { return std::addressof(x); } pointer allocate(size_type n, typename AlignedAllocator<void, Align>::const_pointer = 0) { const size_type alignment = static_cast<size_type>( Align ); void* ptr = detail::allocate_aligned_memory(alignment , n * sizeof(T)); if (ptr == nullptr) { throw std::bad_alloc(); } return reinterpret_cast<pointer>(ptr); } void deallocate(pointer p, size_type) noexcept { return detail::deallocate_aligned_memory(p); } template <class U, class ...Args> void construct(U* p, Args&&... args) { ::new(reinterpret_cast<void*>(p)) U(std::forward<Args>(args)...); } void destroy(pointer p) { p->~T(); } }; template <typename T, Alignment TAlign, typename U, Alignment UAlign> inline bool operator== (const AlignedAllocator<T,TAlign>&, const AlignedAllocator<U, UAlign>&) noexcept { return TAlign == UAlign; } template <typename T, Alignment TAlign, typename U, Alignment UAlign> inline bool operator!= (const AlignedAllocator<T,TAlign>&, const AlignedAllocator<U, UAlign>&) noexcept { return TAlign != UAlign; } 

实际的分配呼叫的实施只是POSIX,但你可以轻松扩展。

 void* detail::allocate_aligned_memory(size_t align, size_t size) { assert(align >= sizeof(void*)); assert(nail::is_power_of_two(align)); if (size == 0) { return nullptr; } void* ptr = nullptr; int rc = posix_memalign(&ptr, align, size); if (rc != 0) { return nullptr; } return ptr; } void detail::deallocate_aligned_memory(void *ptr) noexcept { return free(ptr); } 

需要C ++ 11,顺便说一句。

在即将到来的版本1.56中,Boost库将包括Boost.Align。 在其他内存alignment助手中,它提供了boost::alignment::aligned_allocator ,它可以用于std::allocatorreplace,并允许您指定alignment方式。 请参阅https://boostorg.github.io/align/上的文档;

是的,这应该是可能的。 如果你把这个问题放在谷歌,那么你会得到很多的示例代码,下面是一些有希望的结果:

https://bitbucket.org/marten/alignedallocator/wiki/Home

http://code.google.com/p/mastermind-strategy/source/browse/trunk/src/util/aligned_allocator.hpp?r=167

https://gist.github.com/1471329