12

SQL Server プロセスの CPU 使用率を監視する PowerShell スクリプトを作成しようとしています。この数字のスナップショットを毎日記録して、時間の経過とともに監視し、傾向を監視できるようにしたいと思います。

私のオンライン調査によると、このWMIクエリは私が望むものを与えるはずです:

Get-WmiObject -Query "SELECT PercentProcessorTime FROM win32_PerfFormattedData_PerfProc_Process WHERE Name='SqlServr'"

WMI クエリを実行すると、通常は 30 ~ 50% の値が得られます ここに画像の説明を入力

ただし、リソース モニターでプロセスを監視すると、通常、平均 CPU 使用率は 1% 未満です。 SQL Server 平均 CPU 使用率

WMI クエリは、長期間にわたる平均ではなく、単に CPU 使用率のスナップショットを返していることを知っているので、この 2 つを直接比較することはできません。それでも、リソース モニターの平均は 1% 未満であるため、スナップショットは通常 1% 未満である必要があると思います。

なぜこのような大きな違いがあるのか​​ について何か考えがある人はいますか? また、プロセスの CPU 使用率を正確に測定するにはどうすればよいですか?

4

3 に答える 3

16

ここ数日で WMI とパフォーマンス カウンターについて学んだことはすべてです。

WMI は Windows Management Instrumentation の略です。WMI は、WMI システムおよび Windows COM サブシステムに登録されたクラスのコレクションです。これらのクラスはプロバイダーと呼ばれ、クエリを実行すると動的データを返す任意の数のパブリック プロパティがあります。

Windows には、Windows 環境に関する情報を提供する多数の WMI プロバイダーがプリインストールされています。この質問では、Win32_PerfRawData* プロバイダーと、それから構築される 2 つのラッパーに関心があります。

Win32_PerfRawData* プロバイダーに直接クエリを実行すると、返される数値が恐ろしく見えることに気付くでしょう。これは、これらのプロバイダーが、必要なものを計算するために使用できる生データを提供するためです。

Win32_PerfRawData* プロバイダーとの連携を容易にするために、Microsoft は、PerfMon プロバイダーと Win32_PerfFormattedData* プロバイダーの、照会時により適切な応答を返す 2 つのラッパーを提供しています。

では、プロセスの CPU 使用率を取得するにはどうすればよいでしょうか。次の 3 つのオプションがあります。

  1. Win32_PerfFormattedData_PerfProc_Process プロバイダーから適切にフォーマットされた数値を取得する
  2. PerfMon から適切にフォーマットされた数値を取得する
  3. Win32_PerfRawData_PerfProc_Process を使用して、自分自身の CPU 使用率を計算します

オプション 1 にはバグがあり、すべての場合に機能するとは限らないことがわかります。これは通常、インターネットで提供される回答です。

Win32_PerfFormattedData_PerfProc_Process からこの値を取得する場合は、質問に記載されているクエリを使用できます。これにより、このプロセスのすべてのスレッドの PercentProcessorTime 値の合計が得られます。問題は、複数のコアがある場合、この合計が 100 を超える可能性があることですが、このプロパティは 100 で最大になります。したがって、このプロセスのすべてのスレッドの合計が 100 未満である限り、プロセスのマシンのコア数による PercentProcessorTime プロパティ。

PowerShell の PerfMon からこの値を取得する場合は、Get-Counter "\Process(SqlServr)\% Processor Time". これは、0 から (CoreCount * 100) までの数値を返します。

この値を自分で計算したい場合、Win32_PerfRawData_PerfProc_Process プロバイダーの PercentProcessorTime プロパティは、このプロセスが使用した CPU 時間を返します。そのため、s1 と s2 と呼ぶ 2 つのスナップショットを作成する必要があります。次に、(s2.PercentProcessorTime - s1.PercentProcessorTime) / (s2.TimeStamp_Sys100NS - s1.TimeStamp_Sys100NS) を実行します。

そして最後の言葉です。お役に立てば幸いです。

于 2012-07-19T16:59:49.493 に答える
7

あなたの仮説はほぼ正しいです。単一のスレッド(およびプロセスには常に少なくとも 1 つのスレッドがあります) は、最大で 100% を持つことができますがPercentProcessorTime

  • プロセスは複数のスレッドを持つことができます。
  • システムは、複数の (論理) CPU コアを持つことができます。

したがって、ここ (ハイパースレッディングがオンになっている Intel i7 CPU) には 8 つの論理コアがあり、上位 20 のスレッド (合計を除外) が表示されます (読みやすいように少し整理しています)。

PS > gwmi Win32_PerfFormattedData_PerfProc_Thread |
    ?{$_.Name -notmatch '_Total'} |
    並べ替え PercentProcessorTime -desc |
    最初の 20 を選択 |
    ft -auto Name,IDProcess,IDThread,PercentProcessorTime

名前 IDProcess IDThread PercentProcessorTime
---- ---------- -------- --------------------
アイドル/6 0 0 100
アイドル/3 0 0 100
アイドル/5 0 0 100
アイドル/1 0 0 100
アイドル/7 0 0 96
アイドル/4 0 0 96
アイドル/0 0 0 86
アイドル/2 0 0 68
WmiPrvSE/7#1 7420 6548 43
dwm/4 2260 6776 7
mstsc/2#1 3444 2416 3
powershell/7#2 6352 6552 0
conhost/0#2 6360 6368 0
powershell/5#2 6352 6416 0
powershell/6#2 6352 6420 0
iexplore/7#1 4560 3300 0
Foxit Reader/1 736 5304 0
Foxit Reader/2 736 6252 0
conhost/1#2 6360 1508 0
Foxit Reader/0 736 6164 0

最後の列では、これらすべてを合計すると 800 程度になるはずです。

ただし、これはすべて整数に丸められることに注意してください。いくつかのプロセスについて、Process Explorer の CPU 列 (View | Show Fractional CPU が選択されている場合は丸められません) と比較してください。パーセンテージ値がコア数に対して正規化されるのと同じように注意してくださいwin32_PerfFormattedData_PerfProc_Process(これは表示の一部にすぎません)。

多くのプロセスが数十万サイクルを使用していますが、1% に切り上げるには十分ではありません。

ここに画像の説明を入力

于 2012-07-18T14:52:50.717 に答える
0

試しましたGet-Counterか?

PS PS:\> Get-Counter "\Processus(iexplor*)\% temps processeur"

Timestamp                 CounterSamples
---------                 --------------
17/07/2012 22:39:25       \\jpbhpp2\processus(iexplore#8)\% temps processeur :
                          1,5568026751287

                          \\jpbhpp2\processus(iexplore#7)\% temps processeur :
                          4,6704080253861

                          \\jpbhpp2\processus(iexplore#6)\% temps processeur :
                          0

                          \\jpbhpp2\processus(iexplore#5)\% temps processeur :
                          4,6704080253861

                          \\jpbhpp2\processus(iexplore#4)\% temps processeur :
                          0

                          \\jpbhpp2\processus(iexplore#3)\% temps processeur :
                          0

                          \\jpbhpp2\processus(iexplore#2)\% temps processeur :
                          0

                          \\jpbhpp2\processus(iexplore#1)\% temps processeur :
                          1,5568026751287

                          \\jpbhpp2\processus(iexplore)\% temps processeur :
                          0

ロケール test に依存することに注意してください:

PS PS:\> Get-Counter -ListSet * | where {$_.CounterSetName -contains "processus"}
于 2012-07-17T20:43:20.657 に答える