一般来说,中断延迟没有保证的上限。考虑以下示例:
可屏蔽中断通过执行sti指令禁用,该指令设置IF标志。
通过执行hlt指令,将处理器转换为C1睡眠状态。
发生一个屏蔽中断,其关联性指定它只能在该处理器上处理。
在这种情况下,直到出现一个不可屏蔽中断唤醒处理器并清除IF标志以启用处理可屏蔽中断之前,处理器将不会处理中断。
任何中断(包括不可屏蔽中断)的中断延迟可能达到数百微秒的级别,如果所有应该处理中断的处理器都处于非常深的睡眠状态。在我的Haswell处理器上,C7状态的唤醒延迟为133微秒。如果这对您有影响,可以使用Linux内核参数intel_idle.max_cstate(在使用intel_idle驱动程序时,默认为Intel处理器)或processor.max_cstate(acpi_idle驱动程序)来限制最深的C-state。您可以使用idle=poll告诉内核永远不要将任何核心置于睡眠状态,这可以最小化空闲核心上的中断延迟,当然假设频率由于热量调节而没有降低。使用轮询循环还会降低所有核心的最大睿频,这可能会降低系统的整体性能。
在一个活动的核心(处于C0状态)上,硬件中断只有在核心处于可中断状态时才被接受。这种状态发生在指令边界上,除了字符串指令外,它们是可中断的。Intel没有提供在待处理的中断被接受之前已执行的指令数量的上限。合理的实现可能会停止向ROB(在指令边界处)发出uop,并等到ROB中的所有uop退役之后,才开始执行调用中断处理程序的微码例程。在这样的实现中,中断延迟取决于清除所有未处理uop所需的时间。高延迟指令,如加载、复杂浮点运算和锁定指令,很容易使中断延迟达到数百纳秒的级别。但是,如果其中一个待处理的uop由于任何原因(或某些特定原因)需要微码帮助,处理器可能会选择清除指令及其后续指令而不是调用帮助程序。该实现提高了性能和功耗,但代价是增加了中断延迟。
在另一种旨在最小化中断延迟的实现中,立即清除所有正在进行中的指令而不退役任何指令。但是,这些已经通过管道的刷新指令中的所有指令,其中一些可能已经完成,当中断处理程序返回时需要重新获取并再次通过管道。这会导致性能下降和功耗增加。
硬件中断会耗尽Intel和AMD x86处理器上的存储缓冲区和写组合缓冲区。详情请参见:在汇编指令操作时中断它。
英特尔的一份名为通过使用消息信号中断来减少中断延迟的论文介绍了一种测量来自PCIe设备的中断延迟的方法。该论文使用“中断延迟”一词来指代您提到的论文中所述的“中断响应时间”。您需要在中断到达处理器时某些方式获取一个时间戳,然后再在中断处理程序的开始处获取另一个时间戳。通过将两者相减可以近似计算出中断延迟。问题在于当然是如何获得第一个时间戳(也以与第二个时间戳可比较的方式)。英特尔的论文建议使用PCIe分析仪,它由一个PCIe设备和一个记录设备和CPU之间带有时间戳的所有PCIe流量的应用程序组成。他们使用设备驱动程序在中断处理程序中写入映射到设备的MMIO位置以创建第二个时间戳。
in
或out
指令执行之前,因为它们首先刷新存储缓冲区。iret
是序列化的,因此通常您无法在清空存储缓冲区之前返回用户空间。例如,对于缓冲到其他核心也在竞争的行的 50 个缓存未命中的存储,这可能是很多周期的延迟,以等待 RFO 请求被响应。(BeeOnRope 的删除答案大约是这样说的。) - Peter CordesCLI
),CPU 可能处于系统管理模式;因此,在 CPU 响应 INTR 之前,您可能需要等待数千条指令的完成。同时,也不要忘记HLT
和MWAIT
指令(使 CPU 从等待/睡眠状态恢复所需的时间)。 - Brendan