CPU使用率が1%のプロセスの負荷平均は1.5です。

CPU使用率が1%のプロセスの負荷平均は1.5です。

によると、ほとんどすべてのプロセスがスリープモードにある必要があるにもかかわらず、最近の組み込みシステムの負荷平均が約1.5に達することを確認しましたhtop

このシステムは、buildrootを使用して構築されたライブLinuxカーネル(4.14.126)を実行するデュアルコアCortex-A9です。 initramfsをルートファイルシステムとして使用し、スワップがないためディスクI/Oなし正常動作中。

少しの調査の後、私たちは次のプログラムによってロードが発生したことを発見しました。修正する、これはソフトウェアアップデートのための便利なWebインターフェースを提供します(私たちはそれを使い続けたい)。

timeアプリケーションの平均CPU使用量を見積もるとき(計算して)(ユーザー+システム)/実際)、私が得た値は約1%にすぎず、これは負荷平均1.5を考慮すると大きな意味はありません。

TASK_UNINTERRUPTIBLE負荷平均には、CPU使用率に影響を与えない対応する状態のプロセスも含まれることがわかります。私が理解していないのは、アプリケーションのスレッド/プロセスがなぜその状態にあるのかです。

状況をより詳細に分析するために、以下を使用してカーネルトレースをキャプチャしました。LNGswupdateが実行する唯一の作業は次のとおりです(50ミリ秒ごと)。 ここに画像の説明を入力してください。

これは(100ミリ秒ごとに): ここに画像の説明を入力してください。

ご覧のとおり、ソケットベースのIPCと思われるものがあり、選択を待っているものがあります。。 IPCの場合、一方のスレッドは主にブロックされ、もう一方はブロックされているようにnanosleep()見えaccept()ます。

注:両方のスクリーンショットの時間軸は同じで、IPCには約1分かかります。合計500〜600μs(50ms間隔を考慮すると、観察された1%CPU使用率と非常に一致します)

それでは、ここで負荷が発生する原因は何ですか?

ベストアンサー1

R状態とD状態の両方の操作はLinux負荷を増加させるため、システムはこれら2つの状態のいずれかにあるすべてのスレッドをサンプリングできます。たとえば、

for x in {1..100} ; do ps -aeos,user,comm,wchan | grep "^[RD]" ; sleep 0.1 ; done | sort | uniq -c | sort -nbr | head -20

以下の出力例では、独自のpsプロセスが常にアクティブであることを示す最初の行を無視する必要があります。すべてのサンプリングを実行するプロセスだからです。

# for x in {1..100} ; do
>   ps -aeos,user,comm,wchan | grep "^[RD]"
>   sleep 0.1
> done | sort | uniq -c | sort -nbr | head -20

    100 R root     ps              -
      3 R oracle   oracle_14047_li -
      2 R root     rcu_sched       rcu_gp_kthread
      2 R root     rcu_sched       -
      2 R root     kworker/1:2-eve -
      2 R oracle   perl            -
      2 R oracle   ora_vktm_lin19c hrtimer_nanosleep
      2 D root     md10_raid10     md_super_wait
      2 D oracle   ora_ckpt_linprd md_write_start
      1 R redis    redis-server    -
      1 R oracle   ora_vktm_linprd hrtimer_nanosleep
      1 R oracle   ora_m001_linprd -
      1 D root     xfsaild/dm-18   rq_qos_wait
      1 D oracle   ora_mz00_lin19c x64_sys_io_destroy
      1 D oracle   ora_lg00_lin19c inode_dio_wait
      1 D oracle   ora_dbrm_lin19c msleep

古いカーネルで実行しない限り、新しいカーネルは他のユーザープロセスのWCHAN値をマスクするため、rootとして実行する必要があります。

それより深く入ることができ(psを使用しない)、システムコールおよびカーネルスタックトレース情報をサンプリングして取得することも/proc/PID/syscallできます。この目的のために、Linux Process Snapper()というツールを/proc/PID/stack作成したpsnので、カーネルの追跡に頼らずに、このようなパフォーマンスの問題について非常に高度な詳細な研究を実行できます。

[tanel@linux01 ~]$ sudo psn -G syscall,wchan

Linux Process Snapper v0.18 by Tanel Poder [https://0x.tools]
Sampling /proc/syscall, stat, wchan for 5 seconds... finished.


=== Active Threads ==========================================================================================

 samples | avg_threads | comm             | state                  | syscall         | wchan                 
-------------------------------------------------------------------------------------------------------------
     511 |      255.50 | (kworker/*:*)    | Disk (Uninterruptible) | [kernel_thread] | blkdev_issue_flush 
     506 |      253.00 | (oracle_*_l)     | Disk (Uninterruptible) | pread64         | do_blockdev_direct_IO 
      28 |       14.00 | (oracle_*_l)     | Running (ON CPU)       | [running]       | 0                     
       1 |        0.50 | (collectl)       | Running (ON CPU)       | [running]       | 0                     
       1 |        0.50 | (mysqld)         | Running (ON CPU)       | [running]       | 0                     
       1 |        0.50 | (ora_lgwr_lin*c) | Disk (Uninterruptible) | io_submit       | inode_dio_wait        
       1 |        0.50 | (oracle_*_l)     | Disk (Uninterruptible) | pread64         | 0                     
       1 |        0.50 | (oracle_*_l)     | Running (ON CPU)       | [running]       | SYSC_semtimedop       
       1 |        0.50 | (oracle_*_l)     | Running (ON CPU)       | [running]       | read_events           
       1 |        0.50 | (oracle_*_l)     | Running (ON CPU)       | read            | 0                     
       1 |        0.50 | (oracle_*_l)     | Running (ON CPU)       | semtimedop      | SYSC_semtimedop       

これより詳細に学ぶことができます。関連ブログエントリは次のとおりです。

おすすめ記事