Documentation/cpu-load.txt 說 Linux cpu 負載可能具有誤導性。是否存在未提及的新(或舊)緩解措施?
linux-5.1/Documentation/cpu-load.txt
$$ … $$ 在大多數情況下,
/proc/stat
資訊非常接近地反映了現實,但是由於核心如何/何時收集這些數據的性質,有時它根本不可信。$$ … $$ 如果我們想像系統有一個任務,它以下列方式週期性地燃燒週期:
time line between two timer interrupts |--------------------------------------| ^ ^ |_ something begins working | |_ something goes to sleep (only to be awaken quite soon)
在上述情況下,系統將根據 0% 載入
/proc/stat
(因為定時器中斷總是在系統執行空閑處理程序時發生),但實際上負載更接近 99%。該文件於 2007 年添加。
例如,如果有足夠便宜和可靠的時間源(可靠的 TSC ) ,是否修改了 CPU 調度程序(例如 schedule() 函式)以測量每次程序從可執行轉換為等待的時間?
該文件包括一個範常式序,
smallhog.c
. 根據 LKML.org 上的連結執行緒,它能夠佔用 CPU,而核心只報告了幾個 % 或更少的 CPU 使用率。我嘗試在我目前的系統上編譯和執行它。核心報告程序的 CPU 使用率約為 80%。所以情況似乎發生了一些變化。我們是否確切地知道為什麼
smallhog.c
在這個系統上效率較低?我使用 Fedora 30,Linux 核心 v5.2.0-rc5(大約),在“Intel(R) Core(TM) i5-5300U CPU”上以 64 位模式執行。
lscpu
顯示constant_tsc
和nonstop_tsc
。journalctl -k | grep -iE "TSC|clocksource"
看起來核心發現 TSC 沒有問題。cat /sys/devices/system/clocksource/clocksource0
顯示“tsc”。我看到連結的執行緒說
> > 在所有架構上並非如此,有些架構通過記錄使用者/核心/中斷轉換的時間來進行更準確的記賬…… >
確實。這當然是常見的更無聊的 PC 架構的方式。
(也許hrtick的開發可能會對這個問題產生影響?即使只是為了使其更難利用。或者更容易?或者只是需要稍微不同的程式碼來利用?)。
您說該
smallhog
程序顯示 80% 的 CPU 時間。該 CPU 上剩餘的 20% 時間用於中斷! 為什麼 smallhog.c 在我的系統上顯示不到 100% 的 CPU 使用率?
smallhog
正在做一些非常中斷密集的事情。它的具體戰術顯然被打敗了IRQ_TIME_ACCOUNTING
。見下文。我懷疑仍然有辦法躲避計時器滴答聲:-)。您可能需要一種聰明的方法來預測滴答聲何時觸發。例如通過查看
/proc/interrupts
.config IRQ_TIME_ACCOUNTING bool "Fine granularity task level IRQ time accounting" depends on HAVE_IRQ_TIME_ACCOUNTING && !VIRT_CPU_ACCOUNTING_NATIVE help Select this option to enable fine granularity task irq time accounting. This is done by reading a timestamp on each transitions between softirq and hardirq state, so there can be a small performance impact. If in doubt, say N here.
這個特性在 Fedora 核心配置中啟用(參見 參考資料
/boot/config-*
)。在 x86 CPU 上,它使用 TSC。可以使用啟動時選項禁用該功能,tsc=noirqtime
.$$ * $$ 更準確的會計方法
如問題中所述,PowerPC / S390 具有特定程式碼,可以在每次上下文切換時計算 CPU 時間。這被稱為
VIRT_CPU_ACCOUNTING_NATIVE
。但是你的 x86 核心沒有這個。有一個通用的等價物,稱為
VIRT_CPU_ACCOUNTING_GEN
. (GEN 是“通用”的縮寫)。這個特性是內置在你的 Fedora 核心中的。但預設情況下未啟動此功能。你必須仔細閱讀:-)。
VIRT_CPU_ACCOUNTING_GEN
僅在“完整的 dynticks 系統”上變得活躍。雖然 Fedora 核心配置包括NO_HZ_FULL
,但 Fedora 預設不啟用“full dynticks”。啟用“full dynticks”需要在啟動時指定一個選項nohz_full=
,帶有“adaptive-ticks CPUs”列表。(“至少一個非自適應時鐘 CPU 必須保持線上……”)請參閱linux-5.2-rc5/init/Kconfig:
菜單“CPU/任務時間和統計” 配置 VIRT_CPU_ACCOUNTING 布爾 選擇 提示“Cputime會計” 預設 TICK_CPU_ACCOUNTING 如果 !PPC64 如果 PPC64,則預設為 VIRT_CPU_ACCOUNTING_NATIVE # 一種純基於tick的cputime會計的存根配置 配置 TICK_CPU_ACCOUNTING bool "基於簡單刻度的 cputime 記帳" 取決於 !S390 && !NO_HZ_FULL 幫助 這是基於時鐘的基本 cputime 記帳,它維護 關於每個 jiffies 所花費的使用者、系統和空閒時間的統計資訊 粒度。 如果不確定,請說 Y。 配置 VIRT_CPU_ACCOUNTING_NATIVE bool "確定性任務和 CPU 時間記帳" 取決於 HAVE_VIRT_CPU_ACCOUNTING && !NO_HZ_FULL 選擇 VIRT_CPU_ACCOUNTING 幫助 選擇此選項以啟用更準確的任務和 CPU 時間 會計。這是通過讀取每個 CPU 計數器來完成的 核心進入和退出以及核心內的轉換 在 system、softirq 和 hardirq 狀態之間,所以有一個 性能影響小。在 s390 或 IBM POWER > 5 的情況下, 這也可以計算邏輯分區上的被盜時間 系統。 配置 VIRT_CPU_ACCOUNTING_GEN bool "完整的 dynticks CPU 時間統計" 取決於 HAVE_CONTEXT_TRACKING 取決於 HAVE_VIRT_CPU_ACCOUNTING_GEN 取決於 GENERIC_CLOCKEVENTS 選擇 VIRT_CPU_ACCOUNTING 選擇 CONTEXT_TRACKING 幫助 選擇此選項以啟用完整的任務和 CPU 時間記帳 dynticks 系統。這種會計是通過觀察每個 使用上下文跟踪子系統的核心使用者邊界。 因此,會計是以一些重大損失為代價進行的 高架。 ~~目前,這僅在您進行完整工作時才有用~~ ~~dynticks 子系統開發。~~ 如果不確定,請說 N。 最終選擇
我在最後一段中標記了一行,因為它已經過時了。“完整的 dynticks 子系統”現已開發完成。
$$ * $$TSC 考慮因素
如果 x86 CPU 沒有 TSC,核心不會嘗試將任何其他硬體時鐘源用於
IRQ_TIME_ACCOUNTING
(或用於VIRT_CPU_ACCOUNTING_GEN
)。該程式碼建議接受任何可用的 TSC。我不知道這與沒有
constant_tsc
:-) 的 CPU 配合得如何。雖然我有 99.9% 的把握,相關的維護者都知道這個問題,並且會問為什麼它是可以接受的。請參閱native_sched_clock()和tsc_init():
/* * Fall back to jiffies if there's no TSC available: * ( But note that we still use it if the TSC is marked * unstable. We do this because unlike Time Of Day, * the scheduler clock tolerates small errors and it's * very important for it to be as fast as the platform * can achieve it. ) */