【发布时间】:2018-08-24 06:24:13
【问题描述】:
我相信我会的。由于对齐,矩阵库 Eigen3 可能比我自己的任何矩阵实现都快得多。
我最近开始研究使用 C++ 进行对齐。我偶然发现了 alignas 和 alignof 函数,并决定做一些测试。
我的第一个发现是结构的成员会自动对齐。我们以下面的结构体为例:
struct MyStruct
{
char m_c; // 1 byte
double m_x; // 8 bytes
};
并与这个比较:
struct MyAlignedStruct
{
char m_c; // 1 byte
alignas(8) double m_x; // 8 bytes
};
我使用 alignas 而不是添加填充成员 (char[7]),根据我的理解,这是等效的。
现在,两个结构的内存查看器显示如下:
62 00 00 00 8e a8 79 35 00 00 00 00 00 00 10 40 // MyStruct
62 ff ff ff 24 00 00 00 00 00 00 00 00 00 10 40 // MyAlignedStruct
第一个字节对应一个字符('b')。使用 Mystruct 时,接下来的 7 个字节用 something 填充,最后 8 个字节代表 double。使用 MyAlignedStruct 时,会发生非常相似的情况。 sizeof() 函数为两个结构返回 16 个字节(我希望 MyStruct 为 9 个字节)。
所以我的第一个问题来了:如果编译器自己对齐,为什么我需要对齐?
我的第二个发现是 alignas(..) 不会加快我的程序。我的实验如下。想象一下下面的简单结构:
struct Point
{
double m_x, m_y, m_z;
};
如果我用该结构的实例填充向量,并假设第一个实例是 32 字节对齐的,则每个结构将占用 24 字节,并且字节序列将不再是 32 字节对齐。老实说,我不确定如何通过对齐来提高速度,否则,我很可能不会在这里写。尽管如此,我还是使用了 alignas 来获得以下结构:
alignas(32) struct Point
{
double m_x, m_y, m_z;
};
现在,Point 的连续实例将从 32 字节的倍数开始。我测试了这两个版本:在用结构实例填充一个巨大的向量后,我将所有双精度数相加并记录时间。我发现 32 字节对齐的结构和另一个之间没有区别。
所以我的第二个问题与我的第一个问题相同:为什么需要对齐?
【问题讨论】:
-
简单的答案是通常你不需要,但如果你绝对需要使用原始内存和外来数据结构,那么你可能会发现 alignas 很有用。 alignas 帮助的大多数事情以前都是可能的,但需要付出努力。一个常见的例子是
Struct* s = new (new alignas(Struct) char [ sizeof(Struct)]) Struct,但你必须需要在原始内存中构造对象。
标签: c++ c++11 alignment alignas