X86 返回堆栈缓冲区?

X86 返回堆栈缓冲区?,x86,cpu,cpu-architecture,branch-prediction,micro-architecture,X86,Cpu,Cpu Architecture,Branch Prediction,Micro Architecture,据我所知,返回堆栈缓冲区只支持4到16个条目(来自wiki:),而不是一对键值(基于ret指令位置的索引)。这是真的吗? 当发生上下文切换时,RSB会发生什么情况 假设我们有50个函数没有在返回堆栈缓冲区长度为16的CPU中返回,那么之后会发生什么?这是否意味着所有预测都失败了?你能举例说明吗?递归函数调用中的情况相同吗?BPU可以包含自己的RAS预测器,当它预测BTB中的调用类型时,它将假定的调用NLIP(以下指令的IP)推送到RAS堆栈上。它在BTB中预测的下一个返回将使用RAS的顶部作为预

据我所知,返回堆栈缓冲区只支持4到16个条目(来自wiki:),而不是一对键值(基于ret指令位置的索引)。这是真的吗? 当发生上下文切换时,RSB会发生什么情况


假设我们有50个函数没有在返回堆栈缓冲区长度为16的CPU中返回,那么之后会发生什么?这是否意味着所有预测都失败了?你能举例说明吗?递归函数调用中的情况相同吗?

BPU可以包含自己的RAS预测器,当它预测BTB中的调用类型时,它将假定的调用NLIP(以下指令的IP)推送到RAS堆栈上。它在BTB中预测的下一个返回将使用RAS的顶部作为预测地址(例如,当它预测常规间接分支时,ITA中的并行命中将超过BTB中的目标地址)

BAC将在解码时验证/覆盖这些返回目标预测,方法是将每个调用指令的NLIP推送到自己的RSB,然后将下一个返回地址的预测与此地址进行比较。如果不正确,BAC将发出BAclear,并在管道开始时将下一个IP逻辑重新定位到正确的返回地址(如果RSB损坏,则可能是错误的id)。它可能会用BAC RSB状态覆盖RAS预测器堆栈

在一个实现中,BAC向TOS指针提供其验证的每个分支预测以及直通地址。一旦执行了一个分支并且知道了实际结果,如果出现预测失误,RSB TOS将恢复。我认为更有效的方法是在退役时使用体系结构RSB,在管道刷新/预测失误时将其复制到BAC RSB和RAS预测器中。这可防止恢复到损坏的RSB

RAS预测器可能是一个循环堆栈,根据实现的不同,它可能有也可能没有溢出和下溢检查和保证。当堆栈已满时,新的预测可能会覆盖最旧的预测,使其始终是最新的(而不是防止在堆栈已满时添加预测,这意味着保留一个计数器,以确定无法对其进行预测的调用/返回数)。对于底流,它可能拒绝做出预测,而是使用ITA进行预测。如果RSB下溢,它可能不会覆盖RAS预测器做出的预测


上下文开关的硬件中断导致在执行宏操作的最终uop时清除管道。RSB可能恢复到架构状态,以便在中断后继续。预测器RAS/BAC RSB很可能在微码中被刷新,如果它被损坏,它最终会自行清除。

我认为,返回堆栈缓冲区在上下文开关处重置。Agner的pdf中有一些关于RSB的信息:第3.14节。RSB是一个固定长度的后进先出缓冲区(后进先出;也称为堆栈);在深度调用堆栈中,较旧的返回从RSB推出,并且不会被预测。这种技术在深度递归的情况下几乎没有帮助。注:在最后一点的第3.1节中,Agner说“预测者收集的信息经常由于任务切换和其他上下文切换而丢失”。据我所知,RSB不知道上下文切换:正如osgx所说,它是一个后进先出缓冲区,在上下文切换时会“错误”和预测失误,就像遇到了不匹配的调用或RET一样。对于非常频繁的调用/返回,最常见的情况对于16个条目的“堆栈”来说已经足够浅了,尽管较新的CPU确实会使其更深一些。(如果RSB是空的,有些会退回到标准的间接分支预测。)@PeterCordes是的,但是在BPU进行早期预测的阶段,预测的调用指令的长度是未知的。它必须在BTB条目中由BTB更新在decode或REFIREOH(我知道)处指示。我们是否确定前端(通过RSB)可以在相应呼叫完全解码之前预测ret?假设是,如果
调用
有前缀或很难知道正确的长度,是否有证据表明这会导致预测失误(或需要重新转向或其他什么)?