包含两个特征向量的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.我不明白它的原因,特别是考虑到其他类没有任何填充。任何人都可以解释,或者这是一个错误吗?
答案 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。
继续评论中的讨论,值得注意的是编译器不是你的上帝。并非每个优化都是一个好主意,即使对代码进行微不足道的更改也会对某些优化产生巨大影响。如果你不喜欢你的工具链生产并认为你可以做得更好,那就去做吧!采取一些基准测试,进行更改,然后再次测量。正如你所做的那样,不要花多长时间在上面然后问自己 - 这是否很好地利用了你或你的雇主的时间? :)