包含特征向量的类的奇怪大小

时间:2017-01-12 01:21:43

标签: c++ padding sizeof eigen memory-alignment

包含两个特征向量的C ++类具有奇怪的大小。我有一个问题的MWE:

#include <iostream>
#include "Eigen/Core"

class test0 {
  Eigen::Matrix<double,4,1> R;
  Eigen::Matrix<double,4,1> T;
};

class test1 {
  Eigen::Matrix<double,4,1> R;
  Eigen::Matrix<double,3,1> T;
};

class test2 {
  Eigen::Matrix<double,4,1> R;
  Eigen::Matrix<double,2,1> T;
};

class test3 {
  Eigen::Matrix<double,7,1> T;
};

class test4 {
  Eigen::Matrix<double,3,1> T;
};

int main(int argc, char *argv[])
{
    std::cout << sizeof(test0) << ", " << sizeof(test1) << ", " << sizeof(test2) << ", " << sizeof(test3) << ", " << sizeof(test4) << std::endl;
    return 0;
}

我在我的系统上获得的输出(MacBook Pro,Xcode Clang ++编译器)是:

  

64,64,48,56,24

班级&#34; test1&#34;有一些奇怪的额外填充 - 我本以为它的大小为56.我不明白它的原因,特别是考虑到其他类没有任何填充。任何人都可以解释,或者这是一个错误吗?

2 个答案:

答案 0 :(得分:5)

这是因为Eigen库的实现方式,并且与编译器技巧无关。 Gender的后备存储上有Eigen::Matrix<double, 4, 1>标记,它具有特定于编译器的定义,要求类型在16字节边界上对齐。为了确保这一点,编译器必须在结构的末尾添加8个字节的填充,否则如果你有一个EIGEN_ALIGN_TO_BOUNDARY(16)的数组,第一个矩阵字段将不会在16字节边界上对齐。

Eigen不会试图对test1的后备存储强加类似的要求。

这发生在Eigen::Matrix<double, 7, 1>

答案 1 :(得分:0)

填充要求不是语言规定的,它们实际上是由处理器体系结构强制要求的。您的类正在填充,因此它的宽度为64字节。当然,您可以覆盖它,但这样做是为了使结构整齐地放在内存中,并且可以有效地读取,与高速缓存行对齐。

在什么情况下填充结构是一个复杂的问题,但一般来说“内存便宜,周期不是”。现代计算机有大量的内存,因为当我们接近铜的极限时,性能的提升变得越来越难以找到,所以交换一些性能通常是一个好主意。

可以获得一些额外的阅读here

继续评论中的讨论,值得注意的是编译器不是你的上帝。并非每个优化都是一个好主意,即使对代码进行微不足道的更改也会对某些优化产生巨大影响。如果你不喜欢你的工具链生产并认为你可以做得更好,那就去做吧!采取一些基准测试,进行更改,然后再次测量。正如你所做的那样,不要花多长时间在上面然后问自己 - 这是否很好地利用了你或你的雇主的时间? :)