/proc/statの回数が1秒あたり100回を超えるのはなぜですか?

/proc/statの回数が1秒あたり100回を超えるのはなぜですか?

/proc/stat開発者は一貫していないと報告されたCPU使用率について苦情を吐き出しました。

私の理解は/proc/statティック数を数えることです。カーネル2.6以降、ティック数は100/sに固定されました。

これでCPU1を観察すると、/proc/stat毎秒100ティック以上のティックが計算されるようです。これは不可能です。

このスクリプトは私が計算した方法を示しています。

cat /proc/uptime
b=`awk /cpu1/'{print $2+$3+$4+$5+$6+$7+$8+$9+$10+$11}' /proc/stat`
sleep 1
a=`awk /cpu1/'{print $2+$3+$4+$5+$6+$7+$8+$9+$10+$11}' /proc/stat`
cat /proc/uptime
expr $a - $b

出力例

32.80 19.06
33.86 19.51
CPU1 jiffies/s 137

のフィールドを合計し、/proc/statしばらく待ってからやり直してください。これにより、時には約140の合計差が発生します。かなり安定しています。たぶん、数カウントの上下に動くかもしれません。

カーネルの場合、CONFIG_HZ は 100 です。 250 または 1000 でコンパイルすると、変更は小さくなりますが、まだ残ります。

ユーザースペースと空きフィールドがほとんどの時間を占めるようです。一例では、私は102個のユーザースペースのジフを計算しました。したがって、ユーザー空間は常に占有されます。ただし、完全に予約されたCPUで実行されるアイドルティックは33です。

Linux kernel 4.14.34RTプリエンプションパッチを実行するデュアルコアARMv7プロセッサがあります。同時にリアルタイム制御アプリケーションを実行しています。

私の問題は、/proc/stat数値が一致しないことです。しかし、これを理解するために、なぜ/proc/stat100を超えて数えることができるのか知りたいのです。

編集:スクリプトにcat /proc/uptimeを追加しました。

ベストアンサー1

使用するスクリプトが主な問題です。コンテキスト遷移は待ち時間に関して非常に高価である。 sleep 1スクリプトをスリープ状態にしておきます。タイマーが完了すると、プロセスは再び実行可能になり、CPUの他のコアに再割り当てすることができます(移行)。したがって、基本的に/proc/stat投稿で述べたように、正確に1000msごとにポーリングするわけではありません。

ところで、これはRTコアを評価する良い方法ではありません。

sysjitterSolarflareの例を試してください。システムジッタオープンロードこれにより、カーネルがどのように機能するかをよりよく知ることができます。

主な概念は、コアのタイムスタンプカウンタ(TSC)レジスタを集計し、次の2つの値を比較してコアが実行されるたびに何が起こったかを確認するコア(コアあたり1つの実行スレッド)に無限ループを固定することです。 。実行中のプロセスのプリエンプション差(100hzと仮定)

これにより、サーバーのシステムジッタをよりよく理解し、それをさらに調整することを決定できます。

また、ユースケースでこれらの改善が必要な場合は、CPU分離、アプリケーション専用コア、およびダイナミックティッキングカーネル構成も考慮する必要があります。

awk編集:すべての要件に対して、次の小さなスクリプトを使用することをお勧めします。

#!/usr/bin/awk 

BEGIN { 
    sum1=0;
    sum2=0;
    result=0;
    file="/proc/stat";



while (( getline < file ) > 0 ) {
    if ($1=="cpu1"){ sum1=$2+$3+$4+$5+$6+$7+$8+$9+$10+$11 }; 
    } 
    close(file) ;
    print  "firt time " sum1;
    system("sleep 10");

while (( getline < file ) > 0 ) {
        if ($1=="cpu1") { sum2=$2+$3+$4+$5+$6+$7+$8+$9+$10+$11 }
    }
    close (file)
    print "secont time " sum2;
    result=sum2-sum1;
    print "sum is " result/10;
}

サンプリング時間は10秒以上で、結果を10で割って1秒スライスの平均時間を求めます。

おすすめ記事