在Intel 64与IA-32架构中,存在一类用于跳转到以及跳出程序段的指令:PUSH、POP、CALL、LEAVE与RET。这些指令可以在没有其余指令的干预下隐式地更新栈寄存器(ESP),维护栈内的参数,然后再执行其它相应的操作。在P3处理器之前,这类指令都会被解码成多条μops。

从PM处理器开始,引入了Stack Pointer Tracker技术。PM处理器的decoder中添加了对上述指令的处理逻辑,使得上述指令中的隐式更新ESP部分可以在decoder内完成。这种技术带来了以下便利:

  • 节约解码带宽,因为少输出了一个更新ESP的μop,PUSH、POP、以及RET都变成了单μop指令。
  • 节约执行带宽,因为更新ESP的运算不用在EU内执行了。
  • 提升了out-of-order处理的并行度,因为ESP间的隐式依赖已经被消除。
  • 降低了功耗,因为ESP的更新采用了更小型的硬件。

不过ESP除了上述指令中的隐式运算外,还能进行显式运算。ESP的隐式运算是在decoder中以in-order顺序进行的,而显式运算是在execution unit中以out-of-order顺序进行的,为了使得ESP相关指令正确执行,有必要对decoder以及EU中的ESP进行同步。同步分为两部分:

  • decoder执行完ESP相关运算后,把ESP更新到EU。
  • EU执行完ESP相关运算后,把ESP更新到decoder。

这需要EU以及decoder有对ESP的跟踪能力(Stack Pointer Tracking),不过由于指令在经过renamer的时候有用RAT记录了所有寄存器的映射,因此不单单EU,decoder也能跟踪到ESP的变化。

sync ESP from decoder to EU

decoder向EU更新ESP的实现方法是把ESP分为两部分

ESPP = ESPO + ESPD

其中ESPP是程序员眼中的ESP值(ESP实际值);ESPO是EU中用到的ESP,显式的ESP运算会用到该数值;ESPD是decoder中维护的差值,隐式ESP运算会修改这个数值。以下面的例子来阐述其中机制(仅供参考)

如上图所示,在解码POP/PUSH等隐式修改ESP的指令的时候,可以得到这些指令对ESP修改的差值ESPD,然后通过这些差值,decoder内部的硬件逻辑可以直接算出ESPP并用于这类指令的后续操作。一旦碰上显式访问ESP的指令,如果此时ESPD不为0,则插入一条用于更新ESPO的μop,然后把ESPD置为0。

sync ESP from EU to decoder

由于在pipeline中decoder位于EU的前方,所以有可能会出现这种情况:decoder在计算ESPP时,所需的ESPO还没处理完成,此时ESPP只能依靠推测来得到,即speculative calculation。由于可能会推测错误,因此在得到ESPO后还需要进行判断,如果出错则应该把指令回溯,重新以正确的ESP再次执行。有兴趣的可以查看Reference中的第二三条链接作为拓展阅读。

优化建议

StackPointerTracker会在隐式修改ESP指令之后的第一条显式访问ESP的指令插入一条同步指令,因此如果对ESP的隐式修改与显式访问指令频繁交替,则会不断添加同步μop,因而会影响指令的处理效率。不过无论是隐式修改ESP还是显式访问ESP都是函数不可或缺的一部分,因此在函数体内尽量减少对ESP的隐式显式交替访问(尽量不用PUSH/POP指令),某些critical代码善用inline。

Reference:

Intel® 64 and IA-32 Architectures Optimization Reference Manual

Literature: S. Gochman, et al.: The Intel Pentium M Processor: Microarchitecture and Performance. Intel Technology Journal, vol. 7, no. 2, 2003

M. Bekerman, et al. : Early Load Address Resolution Via Register Tracking

Stack Pointer Tracker的更多相关文章

  1. 栈帧示意图:stack pointer、frame pointer

    更多参考:http://www.embeddedrelated.com/usenet/embedded/show/31646-1.php 一: The calling convention descr ...

  2. 【Debug】IAR在线调试时报错,Warning: Stack pointer is setup to incorrect alignmentStack,芯片使用STM32F103ZET6

    解决办法: Option >Debugger >Download>勾选 Use flash loader 即可,后续取消勾也不再出现报错!

  3. Intel Core Microarchitecture Pipeline

    Intel微处理器近20年从Pentium发展到Skylake,得益于制作工艺上的巨大发展,处理器的性能得到了非常大的增强,功能模块增多,不过其指令处理pipeline的主干部分算不上有特别大的变化, ...

  4. vs中“Stack around the variable was corrupted”的解决方案

    把 project->配置属性->c/c++->代码生成->基本运行时检查 为 默认值 就不会报本异常.具体原因正在研究中... 如果改为其他就有exception. exce ...

  5. java中堆栈(stack)和堆(heap)(还在问静态变量放哪里,局部变量放哪里,静态区在哪里.....进来)

    (1)内存分配的策略 按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的. 静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编 译时就可以给 ...

  6. 堆栈 & Stack and Heap

    What's the difference between a stack and a heap? The differences between the stack and the heap can ...

  7. java中堆栈(stack)和堆(heap)

    原文地址:http://blog.csdn.net/jerryao/article/details/874101 1.内存分配策略 按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈 ...

  8. Java再学习——栈(stack)和堆(heap)

    一.内存分配的策略 按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的. 静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编译时就可以给他们 ...

  9. 数据结构:二级指针与Stack的数组实现

    [简介] Stack,栈结构,即传统的LIFO,后进先出,常用的实现方法有数组法和链表法两种.如果看过我上一篇文章<数据结构:二级指针与不含表头的单链表>,一定会看到其中的关键在于,利用v ...

随机推荐

  1. js 动态调用字符串方法并传入对应参数

    在项目应用中,经常会需要根据业务数据需要动态去拼凑字符串,然后将字符串作为js代码进行执行. js提供eval()来支持.这里分享一个调用函数并传入需要参数的一个方法demo //动态调用自定义js方 ...

  2. Windows下安装RabbitMQ报错:unable to perform an operation on node时的解决方案

    在计算机领域中,想要程序完成各种功能,那么数据的交流和计算是非常重要的.现在已知的程序动作机制有协程,线程和进程. 在同一个程序中,或者说同一个进程中,数据的交流,传递,计算是非常的简单,只要把相关数 ...

  3. Vue-比较方法、计算属性和侦听器

    分别用方法.计算属性和侦听器实现当fristName和lastName改变时,fullName跟着改变. 一.方法: html: <div id="app"> {{fu ...

  4. kafka模型理解

    1.消息发送至一个topic,而这个topic可以由多个partition组成,每条消息在partition中的位置称为offset 2.消息存在有效期,如果设置为2天,则消息2天后会被删除 3.每个 ...

  5. zookeeper-分布式锁的代码实现-【每日五分钟搞定大数据】

    本文涉及到几个zookeeper简单的知识点,永久节点.有序节点.watch机制.比较基础,熟悉的就别看了跳过这篇吧 每个线程在/locks节点下创建一个临时有序节点test_lock_0000000 ...

  6. [WPF]何如在Win7使用Aero2主题

    1. 问题 假设我在Windows10的环境新建一个4.6的WPF项目,添加一个ComboBox,并用Blend在这个ComboBox上右键"编辑模板"->"编辑副 ...

  7. H5 详情和概要标签

    38-详情和概要标签 概要信息 详情信息 --> 郑伊健 简介:郑伊健,1967年10月4日出生于中国香港,籍贯广东恩平,香港影视演员.流行男歌手.1988年参加新秀歌唱大赛加入无线电视,因拍摄 ...

  8. Jury Meeting CodeForces - 854D (前缀和维护)

    Country of Metropolia is holding Olympiad of Metrpolises soon. It mean that all jury members of the ...

  9. Python之自测代码标识__name__=='__main__'

    __name__是python的默认的自测代码标识,其他文件导入该python文件时,不会执行这行代码以下部分. def yangfan(a): print('yangfan %s' %a) prin ...

  10. React不同版本之间需要注意的地方

    React Fiber react fiber指的是react16.0机器之后的版本,相对于之前的版本来说,这一个版本的更新做了很多的优化,所以和之前的版本中的用法可能会发生不同,所以,平常开发中,主 ...