- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
阅读以下内容后:
When an interrupt occurs, what happens to instructions in the pipeline?
关于软件中断会发生什么的信息并不多,但是我们确实了解到以下几点:
相反,异常(如页面错误)会标记受影响的指令。当该指令即将提交时,此时将清除异常之后的所有后续指令,并重定向指令提取。
我想知道管道中的软件中断(INT 0xX)会发生什么,首先,何时检测到它们?是否在预解码阶段检测到了它们?在指令队列中?在解码阶段?还是他们到达后端并立即完成(不要进入预订站),依次退休,退休阶段就知道这是一条INT指令(似乎很浪费)。
假设它是在预解码时拾取的,必须有一种发信号通知IFU停止获取指令或实际上对其进行时钟/电源门控的方法,或者如果它是在指令队列中拾取的,则是一种在队列中先清除指令的方法。这样就必须有一种向某种逻辑(“控制单元”)发出信号的方式,例如为软件中断生成索引(索引到IDT,检查DPL> = CPL> =段RPL等),是幼稚的的建议,但是如果有人对此过程有更好的了解,那就太好了。
我也想知道当这个过程被干扰时,它是如何处理的,即发生硬件中断(记住陷阱不能清除EFLAGS中的IF),现在必须开始一个全新的中断处理和uop生成过程,它将如何处理?之后返回到其处理软件中断的状态。
最佳答案
Andy @Krazy Glew的话是关于在执行“正常”指令期间发现的同步异常,例如mov eax, [rdi]
提高了#PF,如果事实证明RDI指向未映射的页面。1您希望不要出错,因此可以推迟直到退休,以防分支错误预测或较早的异常的情况下,才做任何事情。
但是,是的,他的答案没有详细说明流水线如何针对同步int
陷阱指令进行优化,而我们在解码时知道这将始终导致异常。陷阱指令在整个指令组合中也很少见,因此对其进行优化并不能节省很多精力。只有做简单的事情才值得。
如Andy所说,当前的CPU不会重命名特权级别,因此无法推测为中断/异常处理程序,因此在看到int
或syscall
后暂停获取/解码绝对是明智的选择。我只是要编写int
或“陷阱指令”,但是syscall
/ sysenter
/ sysret
/ iret
和其他特权更改的“分支”指令也是如此。而1-byte versions of int
类似于int3
(0xcc
)和int1
(0xf1
)。有条件的溢出陷阱into
很有趣;对于在无陷阱情况下的非可怕性能,可能会假设它没有被陷阱捕获。 (当然,还有用于VMX扩展的vmcall
和东西,可能还有SGX EENTER
,也许还有其他东西。但是就停滞管道而言,我猜所有陷阱指令都是相同的,除了条件into
之外)
我假设像lfence
一样,CPU不会推测陷阱指令。 没错,将这些uops放入管道中是没有意义的,因为int
之后的所有内容肯定都被刷新了。
如果要从IVT(实模式中断向量表)或IDT(中断描述符表)中获取任何内容,则IDK,以在int
指令在后端变为非推测性之前获取int
处理程序的地址。可能吧(有些陷阱指令(例如syscall
)使用MSR设置处理程序地址,因此从那里开始获取代码可能会很有用,特别是如果它提早触发了L1i未命中。这必须权衡是否看到int
和其他在分支未命中后将指令捕获在错误的路径上。)
误认为命中陷阱指令的可能性可能非常罕见,只要前端看到陷阱指令,就可以从IDT开始加载或一旦前端看到陷阱指令就预取syscall
入口点,这是值得的。处理所有这一切。但这可能不是。将花哨的东西留给微代码可以限制前端的复杂性。即使在syscall
繁重的工作负载中,陷阱也很少见。批量工作以跨用户/内核屏障传递更大的块是一件好事,因为廉价的syscall
在Spectre之后非常困难...
因此,最迟将在issue / rename(已经知道如何暂停(部分)序列化指令)中检测到一个陷阱,并且除非有任何问题,否则不会将更多的uops分配给无序的后端。 int
已停用,并且正在采取异常。
但是似乎有可能在解码中检测到它,而不是在绝对要带异常的指令之后再解码。 (而且我们不知道下一步要去哪里。)解码器阶段确实知道如何停顿,例如用于非法指令陷阱。
假设它是在预解码中拾取的
这可能不切实际,直到完全解码,您才知道它是int
。预解码只是在Intel CPU上进行指令长度查找。我假设int
和syscall
的操作码只是长度相同的许多操作码中的两个。
在硬件中构建以更深入地搜索陷阱指令将比在预解码中花费更多动力。 (请记住,陷阱非常罕见,并且尽早检测到陷阱通常只会节省电量,因此,在将陷阱传递到解码器后停止预解码,您所花费的精力无法比节省更多的精力来寻找它们。
您需要对int
进行解码,以便其微代码可以执行并再次使CPU开始运行中断处理程序,但是是的,从理论上讲,您可以在通过后在循环中进行预解码停止。
例如,在常规解码器中,会识别出分支预测丢失的跳转指令,因此,对于主解码阶段而言,无需进一步处理陷阱即可。
超线程
发现停顿时,您不仅可以对前端进行电源门控。您让另一个逻辑线程拥有所有周期。
超线程使前端在没有后端帮助的情况下开始从IDT指向的内存中获取数据的价值降低。如果另一个线程没有停止,并且可以在清理该陷阱的同时受益于额外的前端带宽,则CPU会做有用的工作。
我当然不会排除从SYSCALL入口点获取代码的情况,因为该地址位于MSR中,并且它是在某些工作负载中与性能相关的少数陷阱之一。
我很好奇的另一件事是,一个逻辑核心切换特权级别对任何性能的影响是否会对另一个核心的性能造成多大的影响。为了测试这一点,您需要构建一些工作负载,这些工作负载会限制您选择的前端问题带宽,后端端口,后端dep链延迟或后端在中长距离上查找ILP的能力(RS大小或ROB大小)。或组合或其他东西。然后,将在内核上运行的该测试工作负载的周期/迭代与自身进行比较,将内核与紧密的dec/jnz
线程,4x pause / dec/jnz
工作负载和syscall
工作负载共享,从而在Linux下进行ENOSYS系统调用。也许还有一个int 0x80
工作量来比较不同的陷阱。
脚注1:异常处理,如正常负载下的#PF。
(离题,re:无辜的看似出错的指令,而不是陷阱,这些指令可以在解码器中检测为引发异常)。
您一直等到提交(退休),因为您不想立即开始进行昂贵的管道刷新,而只是发现该指令在分支未命中(或更早的故障指令)的阴影下并且不应该运行(首先是那个错误的地址)让快速的分支恢复机制抓住它。
这种等待至退休的策略(以及危险的L1d缓存不会将L1d命中的负载值压缩为0,而TLB表示有效,但没有读取权限)是Meltdown和L1TF利用在某些Intel上起作用的关键CPU。 (http://blog.stuffedcow.net/2018/05/meltdown-microarchitecture/)。了解Meltdown对理解高性能CPU中的同步异常处理策略非常有帮助:标记指令并仅在退出后才执行任何操作,这是一种很好的廉价策略,因为异常非常罕见。
如果后端中的任何uop检测到未决的#PF
或其他异常,则让执行单元发信号给前端以停止获取/解码/发出信号显然不值得那么复杂。 (大概是因为这样会更紧密地耦合CPU的其他部分,否则它们之间的距离会很远。)
而且由于在从分支未命中快速恢复期间,错误路径中的指令可能仍在执行中,并且确保仅针对我们认为当前正确的执行路径上的预期错误停止前端,将需要更多跟踪。后端中的所有uop都曾经被认为处于正确的路径上,但是到执行单元的末端时可能不再存在。
如果您没有进行快速恢复,那么后端就应该发送一个“东西不对劲”的信号来阻塞前端,直到后端实际采取异常措施或发现正确的路径,这也许是值得的。
使用SMT(超线程),当一个线程检测到当前正在推测导致故障的(可能正确的)路径时,这可能为其他线程留出更多的前端带宽。
因此,这种想法可能有其优点。我想知道是否有CPU这样做?
关于x86 - 流水线中的软件中断会如何处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54427842/
#include int main() { int i; for( i = 0; i< 10 ; i++ ) { printf("test1 &d", i);
我有一个连接到远程服务器以查询数据的 C# 程序。数据很大,所以查询大约需要 2 分钟才能完成。在这 2 分钟的时间内,互联网中断了。这导致作业无法完成,程序卡在获取数据例程中。 它建立了连接,但在选
语句 1: [2,4,6,7,8].each do |i| (i % 2 == 0) || (puts "Not even" && break) puts i end 声明 2: [2
我想知道 C++ 是否有任何处理中断的方法。我希望一个程序将信息存储在文本文件中,而另一个程序根据文本文件中的内容打印一条语句。由于我希望它尽可能准确,因此我需要在更新程序更新文件时中断打印程序。 最
我正在尝试终止一个线程,但它不会中断或停止。所有这些都是名为 Webots 的软件 Controller 的一部分。我用它来模拟多机器人系统。在每个机器人的 Controller 中,我启动了一个线程
中断10h可以使用的服务有很多, 我想问一下关于其中两个我很困惑的问题 首先是, AH = 06H SCROLL UP WINDOW AH = 07H SCROLL DOWN WINDOW 在 D
我有一个基本的 SQL 问题,如果有两个事件连接,"A"和 "B"到 SQL 服务器,假设两者之间发生死锁,那么为了避免死锁,SQL 服务器将回滚其中一个连接“A”或“B”的交易。假设 SQL Ser
我有一个 mapkit/ View ,它工作正常 - 但我滚动并在 2 - 10 次移动后我的应用程序崩溃了......而且这只是一个“中断”。 这是我的代码的一部分。我认为这是后台线程和数组释放/覆
有什么办法可以做到,比如 C/C# ? 例如(C#风格) for (int i = 0; i Seq.tryFind (fun i -> printfn "%d" i i=66) 在实践中,
我的问题是Haskell如何与系统交互。 例如,IO如何发生? 我对IO monad不感兴趣。或者如何使Haskell打印字符串或读取文件。 我对Haskell和底层操作系统之间的层(如果是这样的话)
你能确认下一个break是否取消了内部for循环吗? for (out in 1:n_old){ id_velho <- old_table_df$id[out] for
我有一个程序可以进行一些数据分析,并且有几百行长。 在程序的早期,我想做一些质量控制,如果没有足够的数据,我希望程序终止并返回到 R 控制台。否则,我希望执行其余代码。 我尝试过break、brows
我有一个 if 语句,用于检查我的对象(向导)是否命中了项目。如果他这样做了,巫师的大小将会改变,他应该能够在与障碍物的 1 次碰撞中幸存。 现在我陷入了“在 1 个障碍物碰撞中幸存”,因为在我的碰撞
我正在尝试使用迭代器来显示很多内容。我不断收到“break;”错误线。它说这是一个无法访问的声明。如有任何帮助,我们将不胜感激。 public Lot getLot(int number) {
我正在创建一个应用程序,我需要在其中处理可能非常庞大且可能需要一些时间的数据。 现在我阅读了很多关于 IntentService 的资料,实际上我已经将它实现为处理 REST 调用的通信类,但现在我试
我有一个自定义的 UITableViewCell。该单元具有三个标签。最左边的“金额”标签具有以下约束。 在单元格的右侧,我有另一个标签,“Label Dollar Amount”。它具有以下约束:
我有以下不和谐嵌入: message.reply({ content: '', embed: { color: 11416728, author
JavaScript 不是我最擅长的技能,但我会尽力解释,所以就这样吧。我有人在我的网站上创建了一个幻灯片菜单,我也使用 jplayer 音乐播放器。 现在一切正常,直到我在顶部添加此脚本。由于某种原
我已经在 Ubuntu 上安装了 android studio,有一个带有损坏图像的 API,我也尝试过重新安装。我应该怎么做才能克服这个问题。 删除它后,它没有在 sdk 管理器中显示 提前致谢。
假设我的站点上有大约 10 个 css 文件。我想把它们合二为一。但是当我组合它们时(只是“连接”文件,以便将它们包含到 html 中),我的样式/布局中断了。这不是路径问题或其他问题,只是选择器无法
我是一名优秀的程序员,十分优秀!