20
20 分分分分分分分分分分 Power Management cpuidle 分 @magoroku15 分分分分分分

20分でわかった事にするパワーマネジメント

Embed Size (px)

Citation preview

Page 1: 20分でわかった事にするパワーマネジメント

20 分でわかった事にするPower Management

cpuidle 編@magoroku15 最底辺活動家

Page 2: 20分でわかった事にするパワーマネジメント

Androidzaurus のつぶやき

• われらの恐竜先生、販売日に Tegra 3 のタブレットをご購入

• 買った、直後の勉強会にて ustream 送出マシンとして華麗にデビュー

• 独自の視点での解析  - お約束ですね -

使用未許諾

Page 3: 20分でわかった事にするパワーマネジメント

Android Zairus の日記

使用未許諾

Page 4: 20分でわかった事にするパワーマネジメント

Governor は Interactive

What dose this mean?

Governor?

Page 5: 20分でわかった事にするパワーマネジメント

Power management  ちょー入門

• 家庭のパワーマネジメント– 照明はコマメに消す– 冷房は設定温度を高めに→ 住人が決める・操作する

• CPU のパワーマネジメント– 不要なものは止める– 処理速度と落とす→ どうやって決めるのか?操作するの

か?

Page 6: 20分でわかった事にするパワーマネジメント

UNIX/BSD/Mac/Linux

KERNEL

App

HDD

System call

idle

動かすプロセスが無いと idle を呼ぶ

Page 7: 20分でわかった事にするパワーマネジメント

BSD 4.3

GENERIC/locore.c1498 .globl Idle1499 Idle: idle:1500 mtpr $0,$IPL # must allow interrupts here1501 tstl _whichqs # look for non-empty queue1502 bneq sw11503 brb idle

Page 8: 20分でわかった事にするパワーマネジメント

Tegra の idleKernel_V9_4_2_7/arch/arm/mach-tegrastatic int tegra_cpuidle_register_device(unsigned int cpu) //

cpuidleへの登録{

:state->enter = tegra_idle_enter_lp2;:

}static inline void tegra_idle_lp2(struct cpuidle_device *dev, struct cpuidle_state *state){#ifdef CONFIG_ARCH_TEGRA_2x_SOC // tegra2の場合 tegra2_idle_lp2(dev, state);#endif#ifdef CONFIG_ARCH_TEGRA_3x_SOC // tegra3の場合 tegra3_idle_lp2(dev, state);#endif}

Page 9: 20分でわかった事にするパワーマネジメント

Tegra3 の idleKernel_V9_4_2_7/arch/arm/mach-tegra/sleep.Svoid tegra3_idle_lp2(struct cpuidle_device *dev, struct cpuidle_state *state){ s64 request = ktime_to_us(tick_nohz_get_sleep_length()); bool last_cpu = tegra_set_cpu_in_lp2(dev->cpu);

cpu_pm_enter();

if (last_cpu && (dev->cpu == 0)) // CPU0だけ別扱い tegra3_idle_enter_lp2_cpu_0(dev, state, request); else tegra3_idle_enter_lp2_cpu_n(dev, state, request);

cpu_pm_exit(); tegra_clear_cpu_in_lp2(dev->cpu);}

Page 10: 20分でわかった事にするパワーマネジメント

Tegra3 の idleKernel_V9_4_2_7/arch/arm/mach-tegra/sleep.SENTRY(tegra_cpu_wfi) cpu_id r0 cpu_to_halt_reg r1, r0 cpu_to_csr_reg r2, r0 mov32 r0, TEGRA_FLOW_CTRL_VIRT mov r3, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG str r3, [r0, r2] @ clear event & interrupt status mov r3, #FLOW_CTRL_WAIT_FOR_INTERRUPT | FLOW_CTRL_JTAG_RESUME str r3, [r0, r1] @ put flow controller in wait irq

mode dsb wfi mov r3, #0 str r3, [r0, r1] @ clear flow controller halt status mov r3, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG str r3, [r0, r2] @ clear event & interrupt status dsb mov pc, lrENDPROC(tegra_cpu_wfi)

Page 11: 20分でわかった事にするパワーマネジメント

WFI   Wait For Interrupt

• ARM の命令• 割り込が発生するまで、 CPU を低電力モードで命

令の実行を止める• 眠りの深さ / 寝起きの良さ– 深く眠ると

• 電力低減効果大 / 寝起きは悪い• もっさり

– 浅く眠ると• 電力低減効果小 / 寝起きは良い• さくさく

• WFI を呼ぶ前に眠りの深さを指定する

Page 12: 20分でわかった事にするパワーマネジメント

おっと• この時点で Tegra の State を理解していな

い事に気づく• Flow controller って何?

Page 13: 20分でわかった事にするパワーマネジメント

Omap3 の idleint __init omap3_idle_init(void){

:state->enter = (state->flags & CPUIDLE_FLAG_CHECK_BM) ?

omap3_enter_idle_bm : omap3_enter_idle;:

}

static int omap3_enter_idle(struct cpuidle_device *dev, struct cpuidle_state *state){

:}

Page 14: 20分でわかった事にするパワーマネジメント

omap3 のC - ステート#define OMAP3_STATE_C1 0 /* C1 - MPU WFI + Core active */

#define OMAP3_STATE_C2 1 /* C2 - MPU WFI + Core inactive */#define OMAP3_STATE_C3 2 /* C3 - MPU CSWR + Core inactive */#define OMAP3_STATE_C4 3 /* C4 - MPU OFF + Core iactive */#define OMAP3_STATE_C5 4 /* C5 - MPU RET + Core RET */#define OMAP3_STATE_C6 5 /* C6 - MPU OFF + Core RET */#define OMAP3_STATE_C7 6 /* C7 - MPU OFF + Core OFF */

昼寝IDLE

爆睡

Page 15: 20分でわかった事にするパワーマネジメント

ステートの指定はどうするの?• CPUIdle Framework– CPU依存の C ステート– Governor( 統治者 ) によるポリシーベースの管

理– /sys/power/cpuidle_deepest_state– /sys/proc/pm_prepwstst

• Governor– “ladder”,”menu”– drivers/cpuidle/governors

Page 16: 20分でわかった事にするパワーマネジメント

cpuidle の構成

/sys/devices/syste/cpu/cpuidle ユーザレベルインターフェース

menu ladder

Generic cpuidle

omap3-cpuidle tegra2-cpuidle

Governor

Cpuidle アーキ無依存

tegra3-cpuidle Cpuidle アーキ依存

Page 17: 20分でわかった事にするパワーマネジメント

cpuidle

• 実行可能なプロセスがない状態を管理– 昔は単純な停止 or ループ– ARM では命令を追加して明に idle を通知 

WFI– WFI を呼ぶ前に、寝る深さ C-State を指定

• 標準で Ladder と menu の Governor– ユーザプログラムで統計情報から指定も可

• 他の省電力機能も cpuidle を起点に動作

Page 18: 20分でわかった事にするパワーマネジメント

他のフレームワーク• cpufreq– 動作周波数を変更– 電源電圧も合わせて変更

• runtime_pm– SoC 内部コアを機能単位ごとに停止するヒントを管理– SoC 内の機能毎に usecount を用意し、 idle のタイミ

ング未使用の機能を止める– Beagle の pm_branch で実機評価可能

• cpuhotplug– cpuidle の C-state 変更を CPU 単位に拡張

Page 19: 20分でわかった事にするパワーマネジメント

上級者向けの話題• Runtime_PM– http://elinux.org/OMAP_Power_Management– http://git.kernel.org/?p=linux/kernel/git/khilman/l

inux-omap-pm.git• Beagleboard で Sleep 時の電流を 8mW にし

た話– http://groups.google.com/group/beagleboard/bro

wse_thread/thread/197a8ef6b46cc828– 回路を改造して、ボード上のコントローラの

電源供給を止める

Page 20: 20分でわかった事にするパワーマネジメント

おわり