【问题标题】:C++ memory alignment questionC++内存对齐问题
【发布时间】:2011-05-25 15:15:04
【问题描述】:

一行代码抵得上一千字:)这是我的问题:

/* Platform specific 16-byte alignment macro switch.
   On Visual C++ it would substitute __declspec(align(16)).
   On GCC it substitutes __attribute__((aligned (16))).
*/
#define ALIGN_16 ...

struct ALIGN_16 A {...};

A* ptr = new A;
A* ptr2 = new A[20];

assert(size_t(ptr) % 16 == 0);

for (int i=0; i<20; ++i)
    assert(size_t(ptr2+i) % 16 == 0);

assert(sizeof(A) % 16 == 0);

我可以期望所有断言都在支持 SSE 的平台上传递吗?谢谢。

编辑。部分回答。我用 VS2008、GCC 和 ICC 做了一些测试。 MS 编译器确实对齐了 ptrptr2,但是 GCC 和 ICC 未能对齐 ptr2

【问题讨论】:

  • 简直想不通。我在徘徊,如果数组的每个元素也对齐。
  • 标准保证正确分配数组的元素与相关类型正确对齐。然而,这种对齐是一个实现细节,理论上可能是一个字节(即打包对齐)。

标签: c++ gcc alignment icc visual-studio


【解决方案1】:

Is there any guarantee of alignment of address return by C++'s new operation?

换句话说,您可以使用该标准来证明您认为它应该有效的假设是正确的,但在实践中,它可能会在您的脸上爆炸。

Visual C++ 6 没有正确对齐通过new 分配的doubles,所以你去吧。

【讨论】:

  • 较新的编译器呢? GCC 4.xx 和 VS 2008?
  • 我不知道有任何编译器提供与 newmalloc 的 16 字节对齐,这意味着在实践中,断言将失败。
  • @jalf,是的,我就是这么想的。我想它在 C++0x 中“支持”,但考虑到 HeapAlloc 间接保证 8 个字节(因为 Windows 数据结构的默认打包选项是 8 字节对齐),我怀疑这会很快发生。
【解决方案2】:

C++0x 提供了一个新的构造(在[meta.type.synop] 20.7.6.6 其他转换):

std::aligned_storage<Length, Alignment>

据我所知,它保证始终正确对齐。

第二个参数是可选的,默认为最严格的要求(因此不精确它总是安全的,但如果你愿意尝试的话,你可以更紧凑地打包你的类型)。

除了bugs,编译器也必须遵守要求。如果您没有 C++0x,可以在 tr1 命名空间或 Boost 上找到它。

您是唯一可以测试您的特定编译器是否满足此请求的人 :)

注意:在gcc-4.3.2上,实现为:

template<std::size_t _Len, std::size_t _Align = /**/>
struct aligned_storage
{
  union type
  {
    unsigned char __data[_Len];
    struct __attribute__((__aligned__((_Align)))) { } __align;
  };
};

【讨论】:

  • 对象是用new 分配的,这(通常)不遵守特定的对齐要求。 (它通常只为您提供 8 字节对齐的内存,这对于大多数用途来说已经足够了)
  • @jalf: 但标准要求new 返回一段适当对齐的内存(来自 3.7.4.1 [basic.std.dynamic.allocation] $2),除非我不明白以便它可以转换为具有基本对齐要求的任何完整对象类型的指针 (3.11) 并且从 3.11 [basic.align] $2 基本对齐由对齐更少表示大于或等于实现在所有上下文中支持的最大对齐,即等于 alignof(std::max_align_t) (18.2)。
  • ... 所以我想说如果new只返回8字节对齐的值并且std::max_align_t优于8,那么实现是不合格的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-24
  • 2018-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-03
  • 2018-05-04
相关资源
最近更新 更多