Linux

Documentation/cpu-load.txt 說 Linux cpu 負載可能具有誤導性。是否存在未提及的新(或舊)緩解措施?

  • July 10, 2019

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_tscnonstop_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. )
*/

引用自:https://unix.stackexchange.com/questions/527416