boost aligned_allocator 对齐参数不影响实际对齐

Posted

技术标签:

【中文标题】boost aligned_allocator 对齐参数不影响实际对齐【英文标题】:boost aligned_allocator alignment parameter does not affect the actual alignment 【发布时间】:2015-11-11 00:27:28 【问题描述】:

我正在使用 boost::alignment::aligned_allocator 来对齐向量的元素。

但是,我注意到我无法在文档中解释的行为:如果我通过关键字 alignas 指定对齐方式,它会按预期工作,但如果我使用分配器的模板参数则不会。

实际上,我找不到这个 tempoate 参数的原因,它似乎对实际对齐没有任何影响(即如果我有 alignas(64) 和 16 作为对齐模板参数,无论如何它将使用 64)。

我用 g++ 4.9 和 clang 3.6 测试了以下代码,得到了相同的输出。 As 和 Bs 都应该对齐。但是 B 对象根本没有对齐。

谢谢!

#include <iostream>
#include <vector>
#include <algorithm>

#include <boost/align/aligned_allocator.hpp>

using namespace std;

struct alignas(64) A  ;
struct B  ;

template <int _AlignT = 64, typename _ContainerT>
bool is_aligned(_ContainerT&& c)

    return all_of(begin(c), end(c), [](auto& e)  return (ptrdiff_t)&e % _AlignT == 0; );


int main()

    std::vector<A, boost::alignment::aligned_allocator<A>> va(3);
    cout << "A aligned:" << boolalpha << is_aligned(va) << endl;

    std::vector<B, boost::alignment::aligned_allocator<B, 64>> vb(3);
    cout << "B aligned:" << boolalpha << is_aligned(vb) << endl;

    for_each(begin(vb), end(vb), [](auto& e)  cout << (void*)&e << endl; );

    return 0;

输出:

A aligned:true
B aligned:false
0xaeb180
0xaeb181
0xaeb182

【问题讨论】:

这不是aligned_allocator,而是std::vector 用来将值放入分配的内存块的方法。 aligned_allocator 似乎使分配的 block 按指定对齐,但不是块中的各个元素。 【参考方案1】:

正如在 cmets 中指出的那样,_boost::alignment::aligned_allocator_ 确实负责 元素的对齐 - 即 std::vector 使用的整个内存块- 但不是每个元素

为了使 std::vector 的所有元素对齐,而不仅仅是第一个,alignas 和对齐模板参数都必须使用

这里有一个例子清楚地说明了这一点:

#include <iostream>
#include <vector>
#include <algorithm>

#include <boost/align/aligned_allocator.hpp>

using namespace std;

struct alignas(64) A  ;
struct B  ;

template <int _AlignT = 64, typename _ContainerT>
bool is_aligned(_ContainerT&& c)

    return all_of(begin(c), end(c), [](auto& e)  return (ptrdiff_t)&e % _AlignT == 0; );


int main()

    
        std::vector<A> vc(1);
        cout << "vector<A> aligned: " << boolalpha << is_aligned(vc) << endl;
        vc.resize(3);
        cout << "vector<A>'s elements aligned: " << boolalpha << is_aligned(vc) << endl;
    

    
        std::vector<B, boost::alignment::aligned_allocator<B, 64>> ve(1);
        cout << "vector<B, aligned_alloc> aligned: " << boolalpha << is_aligned(ve) << endl;
        ve.resize(3);
        cout << "vector<B, aligned_alloc>'s elements aligned: " << boolalpha << is_aligned(ve) << endl;
    

    
        std::vector<A, boost::alignment::aligned_allocator<A, 64>> vd(3);
        cout << "vector<A, aligned_alloc> aligned: " << boolalpha << is_aligned(vd) << endl;
        vd.resize(3);
        cout << "vector<A, aligned_alloc>'s elements aligned: " << boolalpha << is_aligned(vd) << endl;
    

    return 0;

输出:

vector<A> aligned: false
vector<A>'s elements aligned: false
vector<B, aligned_alloc> aligned: true
vector<B, aligned_alloc>'s elements aligned: false
vector<A, aligned_alloc> aligned: true
vector<A, aligned_alloc>'s elements aligned: true

注意在std::vector的情况下,正如我指定的alignas(64),容器本身不是对齐的,而是每个元素之间的距离是 64 字节:

vector<A> element: 0x75b060
vector<A> element: 0x75b0a0
vector<A> element: 0x75b0e0

【讨论】:

以上是关于boost aligned_allocator 对齐参数不影响实际对齐的主要内容,如果未能解决你的问题,请参考以下文章

C11aligned_alloc分配的内存重新分配是不是保持对齐?

在 MS Visual Studio 2013 中,我可以使用啥来代替 std::aligned_alloc?

特征不对齐断言

C ++ BOOST对`boost :: filesystem :: detail :: copy_file的未定义引用

对 boost::serialization 的未定义引用

boost 变体对常用方法的简单调用