c++ - std::vector 应该尊重 alignof(value_type) 吗?

标签 c++ c++11 alignment containers

如果我定义一个具有特定对齐要求的简单类型,该类型的 std::vector<t> 难道不应该为每个元素 遵守对齐吗?

考虑下面的例子

typedef std::array<double,3> alignas(32) avx_point;
std::vector<avx_point> x(10);
assert(!(std::ptrdiff_t(&(x[0]))&31) &&   // assert that x[0] is 32-byte aligned
       !(std::ptrdiff_t(&(x[1]))&31));    // assert that x[1] is 32-byte aligned

我发现 clang 3.2(带或不带 -stdlib=libc++)悄悄地(没有任何警告)违反了对齐要求,而 gcc 4.8.0 发出警告,它忽略了 std::vector(英特尔编译器)的模板参数上的属性太愚蠢了,无法理解 alignas,但如果我改用 __declspec(align(32)),它的行为就像 clang)。两者都创建触发断言的代码。

那么,这是正确的行为还是 clang(和 icpc)的错误以及 gcc 的问题?

编辑 回答评论中提出的一个问题:如果我定义

typedef typename std::aligned_storage<sizeof (avx_point),
                                      alignof(avx_point)>::type avx_storage;

我明白了

sizeof (avx_storage) == 32;
alignof(avx_storage) == 32;

但是 std::vector<avx_storage> 仍然无法为 clang 和 gcc 对齐第一个元素(因此也无法对齐所有其他元素)(这次没有警告)。因此,这些实现显然存在两个问题:首先,std::allocator<type> 甚至忽略了第一个元素的任何对齐要求(非法?),其次,没有应用填充来确保后续元素的对齐。

–––––––––––

编辑 有一个关于如何获得适合 SSE/AVX 操作对齐的内存的 related, more practical question。相反,我想知道 std::vector<> (或 std::allocator<> )是否不应该遵守 C++ 标准(截至 2011 年)的 alignas 。其他问题的答案都不是这个问题的合适答案。

最佳答案

first, that std::allocator ignores any alignment requirements even for the first element (illegal?)

我远不是分配器方面的专家,但不幸的是,在我看来,这是合法行为。更准确地说,分配器可能会忽略请求的对齐。事实上,[allocator.requirements],17.6.3.5/6 状态:

If the alignment associated with a specific over-aligned type is not supported by an allocator, instantiation of the allocator for that type may fail. The allocator also may silently ignore the requested alignment.

您可以编写自己的分配器来为您提供对齐的内存。我以前在工作中这样做过,但不幸的是,出于版权原因,我不能透露代码 :-( 我只能说,这是显而易见的事情:它基于 _aligned_malloc_aligned_free(这是 Microsoft 的扩展)。或者您可以在 Google 上搜索“对齐的分配器”,然后会出现一些选项,其中之一是

https://gist.github.com/donny-dont/1471329

我强调,我不是这个对齐分配器的作者,而且我从未使用过它。

更新

上面的对齐分配器适用于 Visual Studio/Windows,但它可以用作在其他平台上实现对齐分配器的基础。您可以使用 posix memalign函数族或 C11 函数 aligned_alloc

参见 this发布。

关于c++ - std::vector 应该尊重 alignof(value_type) 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16425359/

相关文章:

c++ - 无法从 'initializer-list' 转换为 'std::initializer_list<Keyword> &'

android - 表格布局对齐

latex - 表格,表格,tabularx 垂直对齐, latex

android - 操作栏对齐按钮

c++ - 在 TreeView 中双击后焦点丢失

c++ - 求解斐波那契数列在函数中递归返回void

c++ - 填充指向 vector 元素的指针的无序队列

c++ - 创建宏以将 token (参数)一个一个地收集到列表中

c++ - 任意 double 容器的模板语法是什么?

c++ - std::move weak_ptr::lock 的返回值弄乱了 shared_ptr 的引用计数?