最近我看到编译器如何组合两个32位整数,它们是类属性的值并将它们存储为64位整数。我现在的问题是,为什么要这样做?结合整数有什么好处?
例如,如果我们有类的以下属性
class FooBar {
int x = 1;
int y = 100;
}
所以而不是
i32 = 00000001
i32 = 01100100
我们得到:
i64 = 0000000101100100
你为什么要把它们结合起来?
答案 0 :(得分:11)
现有的(正如我写的那样)答案和评论虽然部分正确,却忽视了这种优化的重点。它是用一条指令替换两条指令(使用32位数据)(使用64位数据)。这导致代码大小和执行时间略有减少。
编译器使用一条64位指令初始化两个变量(因为它们共享连续的内存地址)。变量是分开的,将单独访问。不需要移动或掩蔽。
当初始化许多成员时,在构造函数中经常会出现这种情况。一个常见的情况是零初始化,其中编译器将寄存器归零,然后使用该值初始化多个成员,将写入与连续存储器地址组合,具有更大的单个写入(例如,通过写入16位短零值而不是两个8位的。)
答案 1 :(得分:5)
我相信你正在观察优化。英特尔指令(如PADDSW
)假定多个打包操作数。
https://en.wikipedia.org/wiki/X86_instruction_listings
在64位架构缓存中仅使用1个条目也有好处。
如果您只需要其中一个值,则需要解压缩成本,但我怀疑无论代码优化器运行的是什么,估计都会有更好的节省值。
将C结构的所有成员对齐到单词边界以前是正常的。这是一个char
,int
不会打包,而是与机器的字大小对齐。因此,struct { char, int}
将具有8个字节的sizeof(..)
。我猜这种情况有所改变?
非常有趣。