簡體   English   中英

現代 x86 CPU 中是否有一個計數器,它只計算在中斷處理程序中花費的時間(或周期)?

[英]Is there a counter in modern x86 CPUs which only counts the time (or cycles) spent in interrupt handlers?

這不是一個重復的問題。 有人聲稱這個問題是這個問題的副本。 但是,我沒有提到“Linux”或“內核”(標簽和文本中都沒有)。 因此,聲稱這是處理 Linux 和 perf 的問題的重復是錯誤的。

我想知道如何在沒有外部程序的情況下測量中斷時間。 換句話說,我想自己在代碼中進行時間測量,最好使用硬件寄存器。 為了這個問題,我們假設沒有操作系統。

說了這么多:

在類似 Pentium-M 處理器上運行的匯編程序中,我想測量某個程序執行所需的時間。 這通常是顯而易見的,有很多文章說明並展示了如何做到這一點,而且我也有自己的可靠方法。

但是,在這種情況下,存在一個問題:程序可能隨時被中斷(通過硬件中斷)。 由於我想測量程序本身的純執行時間,事情變得越來越復雜:

  • 測量整個過程所需的時間(簡單)
  • 測量程序運行時中斷處理程序所需的時間(不是那么容易)
  • 從整個時間中減去中斷時間得到我感興趣的數字

我一直認為在“現代”英特爾 PC CPU 上有一個計數器,它只在 CPU 執行中斷處理程序時計數。 但情況似乎並非如此。 至少,我沒有在 Intel 64 和 IA-32 架構軟件開發人員手冊的“性能監控”一章中找到它。

我已經制定了一個適合我目前需求的解決方案,但是對於未來的情況,它並不像我希望的那樣精確,而且它也不是很優雅。

因此,我想知道我是否錯過了一個硬件計數器,它可以通過僅在執行中斷處理程序時計數(或者僅在執行不在中斷處理程序中的代碼時計數)來幫助我。

禁用中斷來測量純過程執行時間不是一種選擇,因為中斷處理程序中發生的事情可能會影響過程的執行。

該過程和中斷處理程序在同一個內核上運行。

整個代碼(過程和中斷處理程序)在環 0 中運行。

不,對此沒有硬件支持,僅用於編程計數器以在環 0(內核模式)與環 3(用戶空間)中計數。 這就是 Linux perf用來實現perf stat --all-user--all-kernelcycles:u:k修飾符的方法。 (我不確定哪一個環 1 和環 2 被混為一談)。

x86 ISA 不會將處於“中斷處理程序”中的狀態區分為特殊狀態。 這只是一個軟件概念,例如,主流內核中的中斷處理程序可能會通過跳轉到一個名為schedule()的函數來決定是返回到被中斷的任務還是返回某個其他任務。 最終可能會有一個iret (中斷返回),但這並不是“特殊”,除了從當前堆棧中彈出 CS:RIP、RSP 和 RFLAGS 之外,這可能很難用其他指令來模擬。

但是,如果內核上下文切換到之前進行了阻塞系統調用的任務,它可能會通過sysret返回用戶空間,僅在上下文切換回被中斷的任務后很久才運行iret 你不需要做任何特別的事情來告訴 x86 CPU 你已經完成了一個中斷處理程序(可能不像其他一些 ISA),所以 CPU 甚至沒有什么可以監視的。

APIC(外部中斷的中斷控制器)可能需要被戳,讓它知道我們已經准備好處理這種類型的進一步中斷,但 CPU 內核本身可能不會跟蹤這一點。

因此,可以想象假設的 x86 硬件使用幾種不同的啟發式方法來判斷中斷處理程序何時完成,但我認為實際的 x86 硬件 PMU 不會做任何這些。


對於在用戶空間中運行(並且不進行系統調用)的分析代碼的正常情況perf stat --all-user (或手動編程它將使用的 PMU 設置)將完全按照您的意願進行,不計入CPU處於內核模式時的任何內容。 唯一的內核時間將在中斷處理程序中。

但是對於您的情況,您要分析的代碼在環 0 中運行,硬件無法幫助您。

除非你在你的中斷處理程序中做了非常耗時的事情(與其他工作量相比),否則只讓它們被計算就足夠了。 至少對於像“循環”這樣的事件。 如果中斷處理程序導致大量 TLB 未命中或緩存未命中或其他原因,則可能會影響您對其他事件的計數。

您的中斷處理程序可以在開始/結束時運行rdpmc並可能將每個事件的計數匯總到一些全局(或核心本地)變量中,因此您可以從主要計數中減去一些內容。 但這會給每個中斷處理程序增加多個rdpmc指令的開銷。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM