在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. for或者while的标记循环

    for或者while的标记循环 今天在写代码的时候,发现一个for循环前有一个字母,不知道这个是什么语法,后来查了一下,这个语法是用来实现标记循环的功能 这个是代码块 r:for(int rowNum ...

  2. Nginx+IIS简单的部署

    随着互联网项目用户访问量不断上升,单点web服务器是无法满足大型高并发高负载的业务处理的,为了给web服务器做负载均衡方案,打算采用Nginx搭建负载均衡服务器,把用户请求分配到N个服务器来缓解服务器 ...

  3. 性能调优3:硬盘IO性能

    数据库系统严重依赖服务器的资源:CPU,内存和硬盘IO,通常情况下,内存是数据的读写性能最高的存储介质,但是,内存的价格昂贵,这使得系统能够配置的内存容量受到限制,不能大规模用于数据存储:并且内存是易 ...

  4. Omi教程-组件通讯攻略大全

    组件通讯 Omi框架组建间的通讯非常遍历灵活,因为有许多可选方案进行通讯: 通过在组件上声明 data-* 传递给子节点 通过在组件上声明 data 传递给子节点 (支持复杂数据类型的映射) 父容器设 ...

  5. Jmeter(三十八)while控制器实现ssh三次重连

    在jmeter中,可以使用SSH协议连接主机进行相关操作, 步骤如下 首先添加一个ssh command  我们的测试交流群:317765580 在command中填写远程连接的必要信息 结果树中可以 ...

  6. Leetcode 2. Add Two Numbers(medium)

    You are given two non-empty linked lists representing two non-negative integers. The digits are stor ...

  7. 剑指Offer-- 二叉搜索树中和为某一值的路径

    输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径. 本身题目不是很难,但是因为刚接触pyhon,对一些对象的传 ...

  8. (第十三周)Final阶段成员贡献分

    项目名:食物链教学工具 组名:奋斗吧兄弟 组长:黄兴 组员:李俞寰.杜桥.栾骄阳.王东涵 个人贡献分=基础分+表现分 基础分=5*5*0.5/5=2.5 成员得分如下: 成员 基础分 表现分 个人贡献 ...

  9. PS制作动感酷炫水人街舞照

    一.打开原图素材,用钢笔工具把人物从图中扣取出来,新建一个812 * 1024像素的文档,把抠出的人物拖进来,过程如下图. 二.用你习惯的修图工具把人物的手.脸部.腰部.袜子通通修掉.再补回衣服在透视 ...

  10. java中流的简单小结

    1.分类 按字节流分: InputStream(输出流)     OutputStream(输入流) 按字符流分: Reader Writer  提示:输入.输出是站在程序的角度而言,所有输入流是“读 ...