gpt4 book ai didi

performance - 地址操作数如何影响机器代码的性能和大小?

转载 作者:行者123 更新时间:2023-12-03 17:17:51 26 4
gpt4 key购买 nike

从32位CPU模式开始,有x86体系结构可用的扩展地址操作数。可以指定基址,位移,索引寄存器和比例因子。

例如,我们要遍历32位整数列表(32位长数据结构的数组中的前两个,以%rdi作为数据索引,以%rbx作为基本指针)。

addl   $8, %rdi                # skip eight values: advance index by 8
movl (%rbx, %rdi, 4), %eax # load data: pointer + scaled index
movl 4(%rbx, %rdi, 4), %edx # load data: pointer + scaled index + displacement


据我所知,这种复杂的寻址方式适合单个机器代码指令。但是,这种操作的成本是多少?与使用独立指针计算的简单寻址相比,它有何作用:

addl  $32, %rbx      # skip eight values: move pointer forward by 32 bytes
movl (%rbx), %eax # load data: pointer
addl $4, %rbx # point next value: move pointer forward by 4 bytes
movl (%rbx), %edx # load data: pointer


在后一个示例中,我介绍了一条额外的指令和一个依赖项。但是整数加法非常快,我获得了更简单的地址操作数,并且不再有乘法运算。另一方面,由于允许的比例因子为2的幂,因此乘法下降为位移,这也是非常快的操作。仍然可以用一个加法代替两个加法和一个移位。

这两种方法之间在性能和代码大小上有什么区别?是否有使用扩展寻址操作数的最佳实践?

或者,从C程序员的角度来看,什么是更快的:数组索引或指针算术?



是否有任何用于大小/性能调整的程序集编辑器?我希望我能看到每个汇编指令的机器代码大小,其执行时间(以时钟周期为单位)或依赖关系图。有数千种装配怪胎可以从这种应用程序中受益,所以我敢打赌,类似的东西已经存在!

最佳答案

地址算术运算速度非常快,如果可能,应始终使用它。

但是这里有一个问题遗漏了。

首先,您不能使用地址算术乘以32-8是最大可能的常数。

代码的第一个版本尚未完成,因为它将需要第二条指令来递增rbx。因此,我们有以下两种变体:

inc  rbx          
mov eax, [8*rbx+rdi]




add  rbx, 8
mov eax, [rbx]


这样,两个变体的速度将相同。大小相同-也为6个字节。

因此,哪种代码更好,仅取决于程序上下文-如果我们的寄存器已经包含所需数组单元的地址,请使用mov eax [rbx]

如果我们有一个包含单元格索引的寄存器,另一个包含起始地址,则使用第一个变量。这样,算法结束后,我们仍将在rdi中拥有数组的起始地址。

关于performance - 地址操作数如何影响机器代码的性能和大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18552677/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com