2016-01-30 66 views
3

出于某种原因(数据驻留在boost/interprocess/file_mapping.hpp的虚拟内存中)我编写自己的内存分配。为了实现跨平台的可移植性,我担心通用的内存对齐方式为T。 (注意:T强烈POD或简单的C++标样charint)在 http://en.cppreference.com/w/cpp/types/aligned_storage 从例子中我们可以看到下面的代码:对阵数组元素的访问

... 
typename std::aligned_storage<sizeof(T), alignof(T)>::type data[N]; 
std::size_t m_size = 0; 

public: 
    // Create an object in aligned storage 
    template<typename ...Args> void emplace_back(Args&&... args) 
    { 
     if(m_size >= N) // possible error handling 
      throw std::bad_alloc{}; 
     new(data+m_size) T(std::forward<Args>(args)...); 
..... 

所以不是经常出入data[i]我一直评价对齐的地址。

所以我的问题:

1)不是开销?我可以分配和访问内存(sizeof(data[N]))

2)如果它是开销什么原因使用对齐访问示例中显示?

+0

我认为我们需要一个更完整的例子,但我现在看到的代码似乎是为每个对象调用新的位置,如果它们是对象,并且足够内联将变得“几乎没有”,那么它很有用。一如既往,“这比理想慢”,你必须衡量这一点,而不仅仅是在理论上看代码,因为编译器有时候非常聪明,有时候根本就不是很细微。 –

+0

cppreference上的示例静态矢量类包含一个用于存储数据的char数组。字符或char数组没有对齐保证。如果您现在尝试在任意对齐的数组地址(即不在4字节边界处)存储双精度数据,程序可能会崩溃。因此,正如@Revolver正确指出的那样,char数组必须从一个适合该类型对齐的地址开始(并且将使其中所有将来的元素正确对齐,而实际上没有填充)。 –

回答

0

它不是开销?

也许吧。也许不会。对于大多数类型,我希望aligned_storage::type大小等于包含的类型大小。我希望编译器优化访问不会比原始数组访问更糟糕。

我只能分配和(sizeof(data[N]))
存取存储器如果是架空什么理由使用对齐的例子所示的访问?

是的,您可以分配原始内存(例如使用char数组),但您必须确保它正确对齐您所使用的类型。如果你想按值存储一些未初始化的数组或者在堆栈上分配一些内存,这并不容易。或者如果您正在使用不使用new/malloc且没有对齐属性的自定义内存分配程序。

aligned_storage结构是一个帮助您自动编写自己的东西,否则你会自己写。

+0

“对于大多数类型,我期望aligned_storage :: type大小等于包含的类型大小”:这是一个有趣的假设。这个类存在*具体*的情况下,出于何种原因,本地对齐不足以满足程序的需求。这意味着至少在原始平台上机会接近1,存储大小大于规定的类型大小。 –

+0

@ PeterA.Schneider,我不得不不同意。我通常会在您需要某种类型的原始存储空间时看到此类使用情况,稍后会以新的放置方式填充。在提供的代码片段中,您可以看到用于对齐的模板参数是'alignof(T)',它不会比原始数组引入更多的开销(甚至由于对象大小和数组元素的位置关联而导致单个对象)。如果你真的看完整的代码,你可以看到'aligned_storage'的使用与简单的存储完全一样。 –

+0

仔细检查这个例子,我发现你是对的。只有内部数据数组才需要对齐,它只是元素类型的对齐要求,不是更多,而不是像std向量那样,但是固定大小。所以是的,我改变了主意,并认为机会是1,没有任何开销;-)。 –