首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >装配中的指令跳转成本

装配中的指令跳转成本
EN

Stack Overflow用户
提问于 2018-12-29 14:03:36
回答 2查看 1.6K关注 0票数 1

我一直对组装过程中的跳跃成本感到好奇。

代码语言:javascript
复制
cmp ecx, edx
je SOME_LOCATION # What's the cost of this jump?

它是否需要在查找表中搜索每个跳转,或者它是如何工作的?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-12-29 21:40:09

不,跳跃式并不能进行搜索。汇编程序将标签解析为地址,在大多数情况下,地址被转换为当前指令的偏移量。地址或偏移量被编码在指令中。在运行时,处理器将地址加载到IP寄存器或将偏移量添加到IP寄存器的当前值(以及@Brendan讨论的所有其他影响)。

有一种类型的跳转指令,可用于从表中获取目标。跳转指令从存储器位置读取地址。(指令指定一个位置,因此仍然没有“搜索”。)这条指令可以如下所示:

代码语言:javascript
复制
jmp table[eax*4]

其中eax是包含要跳转到的地址的表中条目的索引。

票数 4
EN

Stack Overflow用户

发布于 2018-12-29 16:26:33

最初(例如8086),跳转的成本与mov的成本并没有太大的不同。

后来CPU增加了缓存,这意味着一些跳转更快(因为它们跳到的代码在缓存中),而一些跳转则更慢(因为它们跳转到的代码不在缓存中)。

甚至以后CPU还添加了“无序”执行,其中条件分支(例如je SOME_LOCATION)将不得不等待,直到“以前的指令被并行执行”中的标志被知道。

这意味着像这样的序列

代码语言:javascript
复制
mov esi, edi 
cmp ecx, edx 
je SOME_LOCATION

可能比将其重新排列为

代码语言:javascript
复制
cmp ecx, edx 
mov esi, edi 
je SOME_LOCATION

增加国旗被人知道的可能性。

甚至后来CPU也增加了投机性的执行。在这种情况下,对于条件分支,CPU只是在实际知道之前(例如,在已知标志之前)猜测它将分支到哪里,如果它猜错了,就会假装它没有执行错误的指令。更具体地说,推测执行的指令在管道开始时被标记,并保存在管道的末尾(在退役时),直到CPU知道它们是否可以提交到可见状态,或者它们是否必须被丢弃。

之后,事情变得更加复杂,有更好的方法来做分支预测,附加的“分支目标”缓冲区等等。

更改代码段的跳转成本更高。在实际模式中,这并不是很糟糕,因为CPU通常只在更改CS.base= value *16时才执行“CS =value* 16”。对于受保护模式,它是一个表查找(查找GDT或LDT条目),解码条目,根据它是哪种条目来决定该做什么,然后是一堆保护检查。对于长模式来说,这有点相似。所有这些都增加了更多的不确定性(例如,表条目在缓存中?)。

最重要的是,有类似TLB错过的事情。例如,jmp [indirectAddress]可以在indirectAddress上造成TLB缺失,然后在堆栈顶部导致TLB失败,然后在新的指令指针处导致TLB丢失;其中每个TLB缺失可能要花费几百个周期。

大多数情况下,跳转的成本可以是从0周期(对于正确预测的跳转)到可能是1000个周期;取决于CPU的大小、跳转的类型、缓存中的内容、分支预测、缓存/TLB遗漏、RAM的速度/速度以及我可能忘记的任何东西。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53970278

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档