CPU負荷を誤って測定している

「プロセッサの負荷」と呼ばれるこのメトリックは、実際には多くの人々に正しく理解されていません。 プロセッサの読み込みとは何ですか? これは私たちのプロセッサがどれほど忙しいですか? いいえ、そうではありません。 はい、はい、WindowsタスクマネージャーからLinuxのtopコマンドまで、すべてのパフォーマンス分析ユーティリティが示す非常に古典的なCPU負荷について話しています。



「プロセッサの90%が現在ロードされている」とは何ですか? おそらく次のように見えると思います:







しかし、実際には次のようになります。







「アイドル」とは、プロセッサがいくつかの命令を実行できることを意味しますが、何かを期待しているため、これを行いません。たとえば、メインメモリからのデータの入出力です。 上図の実際の作業と「アイドル」作業の割合は、実際のサーバー上の実際のアプリケーションの作業で日々目にするものです。 プログラムがほぼ同じ方法で時間を費やす可能性はかなりありますが、あなたはそれについて知りません。



これはあなたにとって何を意味しますか? プロセッサが実際にいくつかの操作を実行し、データのみを予想する時間を理解すると、コードを変更して、RAMとのデータ交換を減らすことができる場合があります。 これは、自動スケーリングポリシーがCPU負荷に直接結び付けられることがあるクラウドプラットフォームの現在の現実で特に当てはまります。つまり、「アイドル」作業の追加のクロックサイクルごとに実際の費用がかかります。



実際にプロセッサの読み込みとは何ですか?



「メトリック」と呼ばれるこのメトリックは、実際には「非アイドル時間」のようなものを意味します。つまり、これは、プロセッサが特別な「アイドル」ストリームを除くすべてのスレッドで費やした時間です。 オペレーティングシステムのカーネル(それが何であれ)は、コンテキストが実行スレッド間で切り替わるときにこの時間を測定します。 コマンド実行スレッドが100ミリ秒動作する非アイドルスレッドに切り替わった場合、OSカーネルはこの時間を、このスレッドで実際の作業を実行するためにCPUが費やした時間と見なします。



このメトリックは、タイムシェアリングオペレーティングシステムの登場と同時にこの形式で初めて登場しました。 Apollo宇宙船の月面モジュール(当時のタイムシェアリングフロントエンドシステム)にあるコンピューターのプログラマーマニュアルでは、アイドルストリームを特別な名前「DUMMY JOB」と呼び、エンジニアはこのスレッドで実行される命令の数をワークフローで実行されるコマンドの数と比較しました-これプロセッサの負荷を理解してもらいました。



それでは、このアプローチの何が問題になっていますか?



今日、プロセッサはRAMよりもはるかに高速になり、データの待機が、「CPU時間」と呼ばれていた時間の大部分を占め始めました。 topコマンドの出力でCPU使用率が高い場合、プロセッサがボトルネック(ヒートシンクとクーラーの下のマザーボード上の鉄片)であると判断できますが、実際にはまったく異なるデバイス(RAMバンク)になります。



状況は時間とともにさらに悪化します。 長い間、プロセッサメーカーは、メモリメーカーがコアへのアクセス速度を向上させ、レイテンシを削減するよりも速くコアの速度を向上させることができました。 2005年のどこかで、周波数3 Hzのプロセッサが市場に登場し、製造業者はコア数の増加、ハイパートレーディング、マルチソケット構成に集中しました。これらすべてがデータ交換の速度にさらに大きな要求を課しました。 プロセッサメーカーは、プロセッサキャッシュ、高速バスなどのサイズを増やすことで、何らかの方法で問題を解決しようとしました。 もちろん、これは少し助けましたが、根本的に流れを変えませんでした。 私たちはすでにほとんどの時間「プロセッサの読み込み」のためにメモリを待っており、状況は悪化の一途をたどっています。



プロセッサが実際に何をしているかを理解する方法



ハードウェアパフォーマンスカウンターを使用します。 Linuxでは、 perfおよびその他の同様のツールを使用して読み取ることができます。 ここでは、たとえば、10秒以内にシステム全体のパフォーマンスを測定します。



# perf stat -a -- sleep 10 Performance counter stats for 'system wide': 641398.723351 task-clock (msec) # 64.116 CPUs utilized (100.00%) 379,651 context-switches # 0.592 K/sec (100.00%) 51,546 cpu-migrations # 0.080 K/sec (100.00%) 13,423,039 page-faults # 0.021 M/sec 1,433,972,173,374 cycles # 2.236 GHz (75.02%) <not supported> stalled-cycles-frontend <not supported> stalled-cycles-backend 1,118,336,816,068 instructions # 0.78 insns per cycle (75.01%) 249,644,142,804 branches # 389.218 M/sec (75.01%) 7,791,449,769 branch-misses # 3.12% of all branches (75.01%) 10.003794539 seconds time elapsed
      
      





ここで重要な指標は「サイクルあたりのインセンス:IPC」であり、これはプロセッサがサイクルあたり平均して完了した命令の数を示します。 簡略化:数値が大きいほど良い。 上記の例では、この数値は0.78であり、一見、それほど悪い結果ではないようです(時間の78%が有用な仕事をしましたか?)。 ただし、このプロセッサでは、可能な最大IPC値は4.0になります(これは、最新のプロセッサが命令を受け取って実行する方法によるものです)。 つまり、IPC値(0.78に等しい)は、命令を実行できる最大速度の19.5%にすぎません。 Skylake以降のIntelプロセッサでは、最大IPC値はすでに5.0です。



雲の中



仮想環境で作業する場合、実際のパフォーマンスカウンターにアクセスできない場合があります(これは、使用するハイパーバイザーとその設定によって異なります)。 これがAmazon EC2でどのように機能するかについての記事です。



データの解釈と対応



IPC <1.0の場合、おめでとうございます。アプリケーションはRAMからのデータを待機しています。 この場合のパフォーマンスを最適化するための戦略は、コード内の命令数の減少ではなく、RAMへのアクセス数の減少、特にNUMAシステムでのキャッシュのより積極的な使用です。 ハードウェアの観点から(これに影響を与えることができる場合)、キャッシュサイズが大きく、メモリとバスが速いプロセッサを選択するのが賢明です。



IPC> 1.0の場合、アプリケーションはデータを待機することによる影響はそれほど多くありませんが、実行される命令の数が多すぎることによる影響は受けません。 より効率的なアルゴリズムを探し、不要な作業を行わず、繰り返し操作の結果をキャッシュします。 Flame Graphsのプロットおよび分析ツールは、物事を整理するための優れた方法です。 ハードウェアの観点からは、より高速なプロセッサーを使用して、コアの数を増やすことができます。



ご覧のとおり、IPC値1.0の線を引きました。 この番号はどこで入手しましたか? 私は自分のプラットフォームのためにそれを計算しました、そしてあなたが私の評価を信用しないなら、あなたはあなた自身のためにそれを計算できます。 これを行うには、2つのアプリケーションを作成します:1つはプロセッサの100%を命令のフローで(RAMの大きなブロックにアクティブにアクセスせずに)ロードし、2つ目は逆にRAMのデータをアクティブに操作して、重い計算を避けます それらのそれぞれのIPCを測定し、平均を取ります。 これは、アーキテクチャのおよそのターニングポイントになります。



パフォーマンス監視ツールが実際に表示するもの



すべてのパフォーマンス監視ツールは、プロセッサの負荷の隣にIPC値を表示する必要があると思います。 これは、たとえばLinuxのtiptopツールで行われます。



 tiptop - [root] Tasks: 96 total, 3 displayed screen 0: default PID [ %CPU] %SYS P Mcycle Minstr IPC %MISS %BMIS %BUS COMMAND 3897 35.3 28.5 4 274.06 178.23 0.65 0.06 0.00 0.0 java 1319+ 5.5 2.6 6 87.32 125.55 1.44 0.34 0.26 0.0 nm-applet 900 0.9 0.0 6 25.91 55.55 2.14 0.12 0.21 0.0 dbus-daemo
      
      





「プロセッサ負荷」という用語の誤った解釈のその他の理由



プロセッサは、RAMからのデータを待機する時間の損失だけでなく、作業をより遅く実行できます。 その他の要因には次のものがあります。





結論



CPU使用率は今日、非常に誤解されている測定基準になっています。これには、RAMからのデータのレイテンシが含まれ、実際のコマンドの実行よりも時間がかかる場合があります。 クロックあたりの命令数(IPC)などの追加のメトリックを使用して、実際のプロセッサ負荷を決定できます。 1.0より小さい値は、メモリとのデータ交換の速度によって制限されることを示し、大きい値は、命令ストリームの大きなプロセッサ負荷を示します。 IPC(または同様のもの)をプロセッサ負荷のすぐ隣に表示するようにパフォーマンス測定ツールを改善する必要があります。これにより、ユーザーは状況を完全に理解できます。 このすべてのデータを取得すると、開発者はコードを最適化するためのいくつかの手段を講じて、最も有用な側面でコードを最適化できます。



All Articles