Assembly 如果找到结构成员,访问速度会更快<;从开始算起128字节?
从中,我读到: 如果 相对于结构或类开头的成员较少 大于128,因为偏移量可以表示为8位有符号 号码。如果相对于结构起点的偏移或 类为128字节或更多,则偏移量必须表示为 32位数字(指令集在8位和32位之间没有任何内容 位偏移)。例如: 这里b的偏移量是400。通过a访问b的任何代码 指针或成员函数(如ReadB)需要将偏移量编码为 32位数字。如果a和b交换,则可以使用 编码为8位有符号数字的偏移量,或在 全部的这使得代码更加紧凑,从而可以使用代码缓存 效率更高。因此,建议使用大型阵列和 其他大对象在结构或类声明中排在最后 最常用的数据成员排在第一位。如果不可能 包含前128字节内的所有数据成员,然后放入最大 前128字节中经常使用的成员 我已经试过了,我发现这个测试程序的汇编输出没有什么不同,如图所示: 输出是Assembly 如果找到结构成员,访问速度会更快<;从开始算起128字节?,assembly,x86,micro-optimization,Assembly,X86,Micro Optimization,从中,我读到: 如果 相对于结构或类开头的成员较少 大于128,因为偏移量可以表示为8位有符号 号码。如果相对于结构起点的偏移或 类为128字节或更多,则偏移量必须表示为 32位数字(指令集在8位和32位之间没有任何内容 位偏移)。例如: 这里b的偏移量是400。通过a访问b的任何代码 指针或成员函数(如ReadB)需要将偏移量编码为 32位数字。如果a和b交换,则可以使用 编码为8位有符号数字的偏移量,或在 全部的这使得代码更加紧凑,从而可以使用代码缓存 效率更高。因此,建议使用大型阵列和 其
push rbp
mov rbp, rsp
sub rsp, 712
mov DWORD PTR [rbp-416], 32
mov DWORD PTR [rbp-432], 16
mov eax, 0
leave
ret
显然,mov DWORD PTR
用于这两种情况
您应该查看asm的
ReadB
,而不是main
;但由于它们是内联定义的,所以除非您调用它们,否则不会生成asm(然后它将与调用函数的代码混合在一起)。让我们把它们移到一边,这样更容易些
class S2 {
public:
int a[100];
int b;
int ReadB();
};
int S2::ReadB() { return b; }
等等
此外,仅查看asm代码不会显示指令的大小。您需要查看实际的机器代码字节。在godbolt中检查“Output:compiletobinary”就可以做到这一点;在一台真正的机器上,您可以编译成一个对象文件,并使用objdump--discomble
或显示机器代码的类似反汇编工具进行转储
有关更新版本,请参阅
这些函数中的每一个都在rdi
中使用this
指针,并且需要将this->b
移动到eax
。因此,它需要在rdi给定的地址加上相关类中b
的偏移量从内存中加载dword。现在你可以看到:
- 当
位于b
之后时,对于a
mov-eax,DWORD-PTR[rdi+0x190]
- 当
在课程开始时,您将获得b
(2字节)用于8b07
mov eax,DWORD PTR[rdi]
- 当
在b
之前,但在新的a
成员int
之后,您将获得other
8b 47 04
mov-eax,DWORD-PTR[rdi+0x4]
- 作为寄存器(指令需要两个字节)
- 作为一个寄存器加上一个有符号8位位移(占用1个额外字节)
- 作为一个寄存器加上一个有符号的32位位移(额外占用4个字节)
“Nothing between”指的是这样一种想法,即您可能希望有一个具有16位位移的表单,该位移足够大,可以容纳位移
400
,但只使用两个额外的字节。但是没有。汇编源代码不显示每个指令的大小。要查看差异,请查看显示每条指令的地址和字节的反汇编或汇编列表。您看不到它,因为您的代码直接在堆栈上寻址,相对于帧指针,而不是结构的基。创建一个指向类的指针的函数。还要注意,建议的优化不会直接影响执行速度。它会影响指令大小,而指令大小可能会或不会对执行速度产生次要影响,这取决于许多其他因素。Dword ptr表示操作数的大小。这并不意味着指令是如何编码的,汇编程序会计算出来。请检查
push rbp
mov rbp, rsp
sub rsp, 712
mov DWORD PTR [rbp-416], 32
mov DWORD PTR [rbp-432], 16
mov eax, 0
leave
ret
class S2 {
public:
int a[100];
int b;
int ReadB();
};
int S2::ReadB() { return b; }