cpufreq概述
cpufreq的核心功能,是通過調整CPU的電壓和頻率,來兼顧系統的性能和功耗。在不需要高性能時,降低電壓和頻率,以降低功耗;在需要高性能時,提高電壓和頻率,以提高性能。
cpufreq軟件框架
對下,cpufreq基於clock、regulator、pmu等模塊實現頻率和電壓的控制。
對上,cpufreq通過cpufreq core、cpufreq governor、cpufreq stats等模塊以sysfs的形式向用戶空間提供頻率的查詢、控制等接口。
內部,cpufreq內部分為core、governor、drivers等模塊。
cpufreq調頻策略
- Performance
性能優先,CPU固定工作在其支持的最高頻率。
- Powersave
功耗優先,CPU固定工作在其支持的最低頻率。
- Userspace
系統將變頻策略的決策權交給用戶態應用程序,並提供了相應的接口供用戶態程序設置CPU 頻率。
- Ondemand
按需動態調整CPU頻率, 只要CPU負載超過閾值up_threshold就會立即設置為最大頻率,其他時候根據負載計算出合適的頻率。
- Conservative
與ondemand不同,Conservative不是一味追求最高頻率,而是平滑地調整CPU頻率,頻率的升降是漸變式的。
- interactive
基於內核任務調度觸發調頻callback。在callback函數中統計兩次調度之間CPU處於idle和busy的時間,計算出CPU負載調頻然后調頻。
- schedutil
schedutil也是基於內核任務調度觸發調頻callback,與interactive不同的是,schedutil使用的負載來自於內核使用任務負載跟蹤技術(PELT/WALT)估計出來的負載。
cpufreq調測命令
- 查詢
以下文件節點均可通過cat命令顯示
# ls /sys/devices/system/cpu/cpu0/cpufreq/
affected_cpus //當前策略作用於哪些online core
cpuinfo_cur_freq //當前CPU硬件頻率
cpuinfo_max_freq //CPU硬件支持的最低頻率
cpuinfo_min_freq //CPU硬件支持的最高頻率
cpuinfo_transition_latency //硬件支持的切換頻率最小間隔
related_cpus //online和offline core
scaling_available_frequencies //軟件支持的頻率列表
scaling_available_governors //支持的策略列表
scaling_cur_freq //軟件設置的當前頻率,通常與cpuinfo_cpus相同,如果出現硬件問題可能導致不一致
scaling_driver //當前使用的driver
scaling_governor //當前使用的governor
scaling_max_freq //軟件governor設置的最高頻率
scaling_min_freq //軟件governor設置的最低頻率
scaling_setspeed //需將governor類型切換為userspace,才會出現,通過echo修改數值,會切換主頻
- 設置
可以通過 echo配置scaling_governor,scaling_max_freq,scaling_min_freq
例如:echo 1400 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
cpufreq編譯配置
#CPU Frequency scaling
CONFIG_CPU_FREQ=y #主開關
#CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y #default gov任選某個宏打開即可,決定了cpufreq初始化使用的governor,后續可在init.rc修改文件結點
#CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
#CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_STAT=y #維測開關,查看cpufreq統計信息:/sys/devices/system/cpu/cpu0/cpufreq/stats
cpufreq模塊初始化
cpufreq的初始化分為3大階段,依次是core層、governor層和drivers層。
- core層
初始化調頻通知鏈表,pure_initcall(init_cpufreq_transition_notifier_list)
創建cpufreq文件結點,core_initcall(cpufreq_core_init)
- governor層
使用cpufreq_register_governor接口注冊各個governor到鏈表中,,例如:
fs_initcall(cpufreq_gov_performance_init);
fs_initcall(cpufreq_gov_powersave_init);
fs_initcall(cpufreq_gov_userspace_init);
fs_initcall(cpufreq_gov_dbs_init);
fs_initcall(sugov_register);
- drivers層
drivers層的初始化在device_initcall或者late_initcall階段。需要完成以下主要任務:
- 調用cpufreq_register_driver注冊驅動
- 驅動的init回調完成硬件層的初始化,包括clk、regulator、pmu的控制
- cpufreq_register_driver接口內部完成policy和governor的設置