应该std :: vector荣誉alignof(value_type)? [英] should std::vector honour alignof(value_type)?

查看:162
本文介绍了应该std :: vector荣誉alignof(value_type)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我定义一个具有某种对齐要求的简单类型,则不应该对所有类型的 std :: vector< t>

$

$

 std :: vector< avx_point> x(10); 
assert(!(std :: ptrdiff_t(&(x [0]))& 31)&&&//确认x [0]是32字节对齐
! :: ptrdiff_t(&(x [1]))& 31)); //断言x [1]是32字节对齐

我发现对齐要求是静默的(没有任何警告)违反了clang 3.2(有或没有 -stdlib = libc ++ ),而gcc 4.8.0发出警告,它忽略模板参数的属性 std :: vector (intel编译器太难理解 alignas ,但如果我使用 __ declspec(align(32))相反,它的行为像clang)。两者都创建触发断言的代码。



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



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

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

我得到

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

std :: vector< avx_storage> 仍然无法对齐clang和gcc(这次没有警告)的第一个元素(因此所有其他元素)。所以显然有两个问题的实现:第一, std :: allocator< type> 忽略任何对齐要求即使对于第一个元素(非法?),第二,没有应用填充以确保后续元素的对齐。

解决方案


忽略任何对齐要求,即使对于第一个元素(非法?)


我远不是一个专家分配器,我,不幸的是,这是法律行为。更确切地说,分配器可以忽略所请求的对齐。事实上,[allocator.requirements],17.6.3.5/6状态:


如果与特定过对齐类型关联的对齐不是则由分配器支持的分配器的实例化
可能失败。 分配器也可能会默认忽略请求的对齐方式


您可以编写自己的分配器记忆。我之前在我的工作,但不幸的是,由于版权的原因,我不能透露代码:-(我可以说,是显而易见的事情:它是基于 _aligned_malloc _aligned_free (这是Microsoft扩展)或者你可以谷歌的对齐分配器和几个选项将会出现,其中之一是



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



我强调,我不是这个对齐分配器的作者,我从来没有使用它。



更新



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



请参见信息。


If I define a simple type with a certain alignment requirement, shouldn't a std::vector<t> of said type honour the alignment for every single element?

Consider the following example

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

I found that the alignment requirement is silently (without any warning) violated by clang 3.2 (with or without -stdlib=libc++), while gcc 4.8.0 issues a warning that it ignores the attributes on the template argument to std::vector (the intel compiler is too daft to understand alignas, but if I use __declspec(align(32)) instead, it behaves like clang). Both create code that triggers the assert.

So, is this correct behaviour or a bug of clang (and icpc) and an issue with gcc?

edit to answer a question raised in the comments: if I define

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

I get

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

but std::vector<avx_storage> still fails to align the first element (and hence all the others too) for clang and gcc (without warning this time). So there are apparently two issues with the implementations: first, that std::allocator<type> ignores any alignment requirements even for the first element (illegal?) and second, that no padding is applied to ensure alignment of subsequent elements.

解决方案

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

I'm far from being an expert on allocators but it seems to me that, unfortunately, this is legal behaviour. More precisely, an allocator might ignore the requested alignment. Indeed, [allocator.requirements], 17.6.3.5/6 states:

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.

You can write your own allocator to give you aligned memory. I've done that before at my work but, unfortunately, for copyright reasons, I cannot disclose the code :-( All I can say, is the obvious thing: it was based on _aligned_malloc and _aligned_free (which are Microsoft extensions). Or you can Google for "aligned allocator" and a few options will come up, one of which is

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

I emphasize that I'm not the author of this aligned allocator and I've never used it.

Update

The aligned allocator above is for Visual Studio/Windows but it can be used as a base for implementing aligned allocators on other platforms. You can use the posix memalign family of functions or the C11 function aligned_alloc.

See this post.

这篇关于应该std :: vector荣誉alignof(value_type)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆