Jetson Nanoにあるnvpmodelコマンド

# はじめに

今さらながらに`nvpmodel`というコマンドを調べてみた。

# コマンドラインヘルプを読み解く

最初に`nvpmodel -h`の結果を読み解く(英語の訳は適当)。

## コマンドオプション

| コマンドオプション | 機能 |
|-----------------|-----|
| -h | ヘルプを表示 |
| --verbose | 詳細ログを有効 |
| --boot | 正常なビルドなら何もしない[^1] |
| -p, --parse | 設定ファイルを読み込むだけ、--verboseと合わせること推奨 |
| -m, --mode \<mode\> | \<mode\>は設定ファイルに定義されたPOWER_MODEL IDの整数値。指定した電力モードに切り替え|
| -f, --conf | 明示的に設定ファイルを指定。他にオプションがなければ指定された設定ファイルをデフォルトに設定。|
| -o, --os \<android,l4t\> | 電力制御のためのOS固有の操作を実行[^2]。|
| -q, --query | 現在の電力モードを表示 |
| -w, --wait | 指定した秒数分実行を遅らせる |
| -u, --udata | 電力モードの設定・表示時に、ユーザデータファイル[^3]の絶対パスを指定。


[^1]: 正常なビルドでないと何が起こる?
[^2]: OS固有って何だ
[^3]: ユーザデータファイルとは?

# 実行してみる

```bash:ターミナル
yamamo-to@jetson-nano:~$ nvpmodel -p --verbose
NVPM VERB: Config file: /etc/nvpmodel.conf
NVPM VERB: parsing done for /etc/nvpmodel.conf
succeed to parse file /etc/nvpmodel.conf.
NVPM VERB: PM_CONFIG: DEFAULT=MAXN(0)
NVPM VERB: PARAM TYPE=FILE NAME=CPU_ONLINE
NVPM VERB: CORE_0 /sys/devices/system/cpu/cpu0/online
NVPM VERB: CORE_1 /sys/devices/system/cpu/cpu1/online
NVPM VERB: CORE_2 /sys/devices/system/cpu/cpu2/online
NVPM VERB: CORE_3 /sys/devices/system/cpu/cpu3/online
NVPM VERB: PARAM TYPE=FILE NAME=GPU_POWER_CONTROL_ENABLE
NVPM VERB: GPU_PWR_CNTL_EN /sys/devices/gpu.0/power/control
NVPM VERB: PARAM TYPE=FILE NAME=GPU_POWER_CONTROL_DISABLE
NVPM VERB: GPU_PWR_CNTL_DIS /sys/devices/gpu.0/power/control
NVPM VERB: PARAM TYPE=CLOCK NAME=CPU_A57
NVPM VERB: FREQ_TABLE /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies
NVPM VERB: MAX_FREQ /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
NVPM VERB: MIN_FREQ /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
NVPM VERB: PARAM TYPE=CLOCK NAME=GPU
NVPM VERB: FREQ_TABLE /sys/devices/gpu.0/devfreq/57000000.gpu/available_frequencies
NVPM VERB: MAX_FREQ /sys/devices/gpu.0/devfreq/57000000.gpu/max_freq
NVPM VERB: MIN_FREQ /sys/devices/gpu.0/devfreq/57000000.gpu/min_freq
NVPM VERB: PARAM TYPE=CLOCK NAME=EMC
NVPM VERB: MAX_FREQ /sys/kernel/nvpmodel_emc_cap/emc_iso_cap
NVPM VERB: 
NVPM VERB: POWER_MODEL: ID=0 NAME=MAXN
NVPM VERB: CPU_ONLINE CORE_0 1
NVPM VERB: CPU_ONLINE CORE_1 1
NVPM VERB: CPU_ONLINE CORE_2 1
NVPM VERB: CPU_ONLINE CORE_3 1
NVPM VERB: CPU_A57 MIN_FREQ 0
NVPM VERB: CPU_A57 MAX_FREQ 2147483647
NVPM VERB: GPU_POWER_CONTROL_ENABLE GPU_PWR_CNTL_EN on
NVPM VERB: GPU MIN_FREQ 0
NVPM VERB: GPU MAX_FREQ 2147483647
NVPM VERB: GPU_POWER_CONTROL_DISABLE GPU_PWR_CNTL_DIS auto
NVPM VERB: EMC MAX_FREQ 0
NVPM VERB: 
NVPM VERB: POWER_MODEL: ID=1 NAME=5W
NVPM VERB: CPU_ONLINE CORE_0 1
NVPM VERB: CPU_ONLINE CORE_1 1
NVPM VERB: CPU_ONLINE CORE_2 0
NVPM VERB: CPU_ONLINE CORE_3 0
NVPM VERB: CPU_A57 MIN_FREQ 0
NVPM VERB: CPU_A57 MAX_FREQ 918000
NVPM VERB: GPU_POWER_CONTROL_ENABLE GPU_PWR_CNTL_EN on
NVPM VERB: GPU MIN_FREQ 0
NVPM VERB: GPU MAX_FREQ 640000000
NVPM VERB: GPU_POWER_CONTROL_DISABLE GPU_PWR_CNTL_DIS auto
NVPM VERB: EMC MAX_FREQ 1600000000
NVPM VERB: 
```

なるほど、デフォルトの設定ファイルは`/etc/nvpmodel.conf`らしい。
中身を覗いてみると以下の記述を確認。

```/etc/nvpmodel.confの一部
...
###########################
#                         #
# POWER_MODEL DEFINITIONS #
#                         #
###########################

# MAXN is the NONE power model to release all constraints
< POWER_MODEL ID=0 NAME=MAXN >
CPU_ONLINE CORE_0 1
CPU_ONLINE CORE_1 1
CPU_ONLINE CORE_2 1
CPU_ONLINE CORE_3 1
CPU_A57 MIN_FREQ  0
CPU_A57 MAX_FREQ -1
GPU_POWER_CONTROL_ENABLE GPU_PWR_CNTL_EN on
GPU MIN_FREQ  0
GPU MAX_FREQ -1
GPU_POWER_CONTROL_DISABLE GPU_PWR_CNTL_DIS auto
EMC MAX_FREQ 0

< POWER_MODEL ID=1 NAME=5W >
CPU_ONLINE CORE_0 1
CPU_ONLINE CORE_1 1
CPU_ONLINE CORE_2 0
CPU_ONLINE CORE_3 0
CPU_A57 MIN_FREQ  0
CPU_A57 MAX_FREQ 918000
GPU_POWER_CONTROL_ENABLE GPU_PWR_CNTL_EN on
GPU MIN_FREQ 0
GPU MAX_FREQ 640000000
GPU_POWER_CONTROL_DISABLE GPU_PWR_CNTL_DIS auto
EMC MAX_FREQ 1600000000

# mandatory section to configure the default mode
< PM_CONFIG DEFAULT=0 >
```

いろいろ見えてきた。例えば

```bash:ターミナル
nvpmodel -m 1
```
というコマンドはCPUの4コア中、2コアのみ使うようにしCPUの最大周波数を896MHzに抑える省電力モード。デフォルト 0 のときはMAXNの4コアということ。

# サービスとの関係

`nvpmodel`はシステムサービスとして登録されており起動時に実行される。systemctlで確認すると

```bash:ターミナル
yamamo-to@jetson-nano:~$ systemctl status nvpmodel.service
● nvpmodel.service - nvpmodel service
   Loaded: loaded (/etc/systemd/system/nvpmodel.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since Sat 2019-06-01 08:34:06 JST; 2h 42min ago
  Process: 4695 ExecStart=/usr/sbin/nvpmodel -f /etc/nvpmodel.conf (code=exited, status=0/SUCCESS)
 Main PID: 4695 (code=exited, status=0/SUCCESS)

 6月 01 08:34:06 jetson-nano systemd[1]: Started nvpmodel service.
```

したがってデフォルト設定を変えたい場合(例えば省電力モードで起動)は`/etc/nvpmodel.conf`を変更すれば良い。

また、似たようなサービスで`jetson_performance.service`を見つけた。こちらはdisabledで実行されていないようだ。

```bash:ターミナル
yamamo-to@jetson-nano:~$ systemctl status jetson_performance.service
● jetson_performance.service - Jetson performance is a script to control jetson_clock.sh and the nvpmodel
   Loaded: loaded (/opt/jetson_stats/jetson_performance.sh; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:systemd-sysv-generator(8)
```

ここに現れる`/opt/jetson_stats/jetson_performance.sh`を確認すると、こちらは`jetson_clocks`を起動する。つまり起動時に最高パフォーマンスで駆動したい場合は

```bash:ターミナル
sudo systemctl enable jetson_performance.service
```
とする。

# まとめ

`nvpmodel`はあらかじめ設定された電力設定に切り替えるためのコマンド。使いそうなコマンドは

- `nvpmodel -m 0` 標準電力モードにする(起動時のデフォルト)
- `nvpmodel -m 1` 省電力モードにする
- `nvpmodel -q --verbose` 現在の電力モード確認

また起動時のデフォルト設定は

- 省電力モードで起動の場合 `/etc/nvpmodel.conf` を変更
- 最大パフォーマンスで起動の場合 `jetson_performance.service`を有効化