[英]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-kernel
或cycles: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.