use*_*136 25
您应该使用带std::
容器的自定义分配器,例如vector
.不记得是谁写了下面的那个,但我用了一段时间它似乎工作(你可能需要_aligned_malloc
改为_mm_malloc
,取决于编译器/平台):
#ifndef ALIGNMENT_ALLOCATOR_H
#define ALIGNMENT_ALLOCATOR_H
#include <stdlib.h>
#include <malloc.h>
template <typename T, std::size_t N = 16>
class AlignmentAllocator {
public:
typedef T value_type;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef T * pointer;
typedef const T * const_pointer;
typedef T & reference;
typedef const T & const_reference;
public:
inline AlignmentAllocator () throw () { }
template <typename T2>
inline AlignmentAllocator (const AlignmentAllocator<T2, N> &) throw () { }
inline ~AlignmentAllocator () throw () { }
inline pointer adress (reference r) {
return &r;
}
inline const_pointer adress (const_reference r) const {
return &r;
}
inline pointer allocate (size_type n) {
return (pointer)_aligned_malloc(n*sizeof(value_type), N);
}
inline void deallocate (pointer p, size_type) {
_aligned_free (p);
}
inline void construct (pointer p, const value_type & wert) {
new (p) value_type (wert);
}
inline void destroy (pointer p) {
p->~value_type ();
}
inline size_type max_size () const throw () {
return size_type (-1) / sizeof (value_type);
}
template <typename T2>
struct rebind {
typedef AlignmentAllocator<T2, N> other;
};
bool operator!=(const AlignmentAllocator<T,N>& other) const {
return !(*this == other);
}
// Returns true if and only if storage allocated from *this
// can be deallocated from other, and vice versa.
// Always returns true for stateless allocators.
bool operator==(const AlignmentAllocator<T,N>& other) const {
return true;
}
};
#endif
Run Code Online (Sandbox Code Playgroud)
像这样使用它(如果需要,将16改为另一个对齐):
std::vector<T, AlignmentAllocator<T, 16> > bla;
Run Code Online (Sandbox Code Playgroud)
但是,这只能确保内存块std::vector
使用的是16字节对齐.如果sizeof(T)
不是16的倍数,则某些元素将不会对齐.根据您的数据类型,这可能不是问题.如果T
是int
(4个字节),则只加载索引为4的倍数的元素.如果是double
(8个字节),则只有2的倍数,等等.
真正的问题是如果你使用类T
,在这种情况下你必须在类本身中指定你的对齐要求(同样,取决于编译器,这可能是不同的;示例是针对GCC):
class __attribute__ ((aligned (16))) Foo {
__attribute__ ((aligned (16))) double u[2];
};
Run Code Online (Sandbox Code Playgroud)
我们差不多完成了!如果您使用Visual C++(至少是版本2010),您将无法使用std::vector
您指定其对齐的类,因为std::vector::resize
.
编译时,如果收到以下错误:
C:\Program Files\Microsoft Visual Studio 10.0\VC\include\vector(870):
error C2719: '_Val': formal parameter with __declspec(align('16')) won't be aligned
Run Code Online (Sandbox Code Playgroud)
您将不得不破解您的stl::vector header
文件:
vector
头文件[C:\ Program Files\Microsoft Visual Studio 10.0\VC\include\vector]void resize( _Ty _Val )
方法[VC2010上的第870行]void resize( const _Ty& _Val )
.Max*_*kin 21
C++标准要求分配函数(malloc()
和operator new()
)为任何标准类型分配适当对齐的内存.由于这些函数没有作为参数接收对齐要求,因此在实践中它意味着所有分配的对齐是相同的,并且是标准类型与最大对齐要求的对齐,这通常是long double
和/或long long
(参见boost max_align union).
与标准C++分配函数相比,向量指令(如SSE和AVX)具有更强的对齐要求(对于128位访问是16字节对齐,对于256位访问是32字节对齐).posix_memalign()
或者memalign()
可用于满足具有更强对齐要求的此类分配.
Dev*_*ull 11
如前所述,您可以使用boost::alignment::aligned_allocator
以下内容而不是编写自己的分配器std::vector
:
#include <vector>
#include <boost/align/aligned_allocator.hpp>
template <typename T>
using aligned_vector = std::vector<T, boost::alignment::aligned_allocator<T, 16>>;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
23150 次 |
最近记录: |