過去のWMI、マイナスCPU使用率、Timestamp_Sys100NS

私は、.NETの System.Management のものを使用して、WMIを使っていくつかのマシンを監視しています。私が使用しているクエリはこれです:

SELECT Timestamp_Sys100NS, PercentProcessorTime 
FROM Win32_PerfRawData_PerfOS_Processor 
WHERE Name='_Total'

それで、私はよく知られている公式を使ってCPU使用率を計算します:

double cpu_usage = (1 - (double)delta_cpu/delta_time) * 100;

それは1台のマシンを除くすべてのマシンで非常にうまく動作します(これまでのところ)。

The problem is that for one machine, which is Windows 2003 server (with hyper-threading enabled, if it matters), I am sometimes getting negative CPU usage values. In other words, the (double)delta_cpu/delta_time expression yields number > 1. I did search the web for hints as to why this could be happening but I found nothing.

このWindows 2003サーバーは特定ですか?それともハイパースレッディング関連の問題ですか?または、それはちょうど予想され、私はちょうどCPU使用量の値または cpu_delta 値をある範囲に固定する必要がありますか?

EDIT: The second weird thing I am observing with this one machine is that the Timestamp_Sys100NS value does not indicate FILETIME like date (ticks since epoch January 1, 1600) but instead it looks like ticks since boot time.

EDIT 2: I have now verified that this problem is across a lot of Windows 2003 servers. And I am apparently not the only one with the same problem.

EDIT 3: I have solved the time stamp issue by querying LastBootUpTime from Win32_OperatingSystem and adding that to the Timestamp_Sys100NS when the value of Timestamp_Sys100NS is too far in the past. That seems to give correct date and time. The code manipulating the date after it is retrieved from Win32_OperatingSystem looks like this:

WbemScripting.SWbemDateTime swbem_time = new WbemScripting.SWbemDateTime();
swbem_time.Value = date_str;
string time_as_file_time_str = swbem_time.GetFileTime(true);
return new DateTimeOffset(epoch.Ticks + long.Parse(time_as_file_time_str),
    swbem_time.UTCSpecified
    ? TimeSpan.FromMinutes(swbem_time.UTC)
    : TimeSpan.Zero);

... UTCに調整...

boot_time = boot_time.UtcDateTime;

... Timestamp_Sys100NS フィールドでWMIによって返されたタイムスタンプ( current )に boot_time

if (time.Year < 2000)
    time = boot_time + current;

EDIT 4: It appears that there are 3 classes of system with respect to Timestamp_Sys100NS:

  1. まず、 Timestamp_Sys100NS の時刻が時代(UTC)からの時刻であるVista +システムです。
  2. 適切な時間を得るために Timestamp_Sys100NS Win32_OperatingSystem.LastBootUpTime に追加する必要があるWindows 2003システムもあります。
  3. 第3のクラスは、上記の追加を行っても、日時が正しい日時になったシステムです。

EDIT 5: Some of the affected machines might have been VMs but not all of them.

18
@ raz3r:私は System.DateTime(Int64) ctorを使用しています(ティックを取ります)、LastBootUpTimeに追加します。私は明日の正確な詳細のみを確認することができます。
追加された 著者 wilx,
LastBootUpTimeをTimeStamp_Sys100NSにどのように追加しましたか?どのような変換をしましたか?
追加された 著者 raz3r,
それはCPUがあなたを使用していることを意味:)
追加された 著者 Iarek Kovtunenko,

3 答え

それは私にとって標準的な「時間同期」問題のように聞こえる。

あなたのシステムのクロックは...クロックです。あなたのコンピュータが外部クロック(Windowsタイムサービスなど)と同期すると、システム時間が後ろにジャンプすることがありますので、あなたの時計は高速に実行されている可能性があります(おそらく実際の時間の99%で1分を完了します)。

代わりに、ユーザーは手動でシステム時刻を調整することができます(たとえば、日付と時刻のコントロールパネル)ので、設計する必要があります(システムの時刻を設定するとユーザーは非常に不幸になります)。

私がこれを解決する方法はクランピングです。通過するのに少なくとも0.0秒の「リアルタイム」を必要とするが、時間調整が後方だけでなく前進するので、最大0.5秒にクランプする。

助けてください

1
追加された
悪い時間情報の効果は一貫していますが、しばらくの間は1回だけではなく、常に発生します。私のコードは5秒ごとにチェックしていました。それは、NTPデーモン/サービスによる段階的な時間調整に苦しんでいないほど長く思える。あなたの答えがその問題を説明するものは何もしません。
追加された 著者 wilx,
0.0秒の最小値は、ゼロによる除算も注意する必要があることを忘れないでください
追加された 著者 JasonS,
私はこれがあなたの問題だと確信していますので、もし私の解決策がうまくいけば、もう一度メッセージを送ってください。
追加された 著者 JasonS,

The formula you are specifically talking about is PERF_100NSEC_TIMER_INV http://msdn.microsoft.com/en-us/library/ms803963.aspx

私はゼロ以下の値を見たことがないので、私は個人的にこの問題に取り組んでいません。

これは私がやっているすべてのことです:

/// 
/// PERF_100NSEC_TIMER_INV algorithm.
/// 
/// 
/// 
/// 
/// 
/// 
public static int CalculatePerf100NsecTimerInv(long n2, UInt64 d2,
                                               long n1, UInt64 d1)
{
    int usage = 0;
    try
    {
        double dataDiff = (n2 - n1);
        double timeDiff = (d2 - d1);
        double dUsage = (1 - (dataDiff/timeDiff)) * 100;

       //Evaluate
        usage = (dUsage >= 0.5) ? Convert.ToInt32(Math.Ceiling(dUsage)) : 0;
    }
    catch { }

   //Return
    return usage;
}

使用法:

// Calculate
int cpuTime =
    MSPerformanceAlgorithms.CalculatePerf100NsecTimerInv(
        current.PercentProcessorTime, current.TimestampSys100Ns,
        previous.PercentProcessorTime, previous.TimestampSys100Ns);

2003のボックスのタスクマネージャでCPU使用率を監視すると、正常に一致します。私はあなたがこれらの値で計算している限り、ゼロよりも小さいものは無視することができると思います。

0
追加された
残念ながら、私は正しい数式を使用しています。
追加された 著者 wilx,
私はあなたができることが他にはたくさんあるとは確信していません。あなたの所見から、スタンプが間違っているという直接的な指標として、LastBootUpTime> Timestamp_Sys100NSかどうかを確認するチェックを追加します。 WMIのリリースには多くの矛盾がありました。彼らは実際には、Windows 2003まで、ネットワークデータとカウンタを追加すると、それほど効果的になることはありませんでした。これはWindows 2003 R1のみで可能ですか? x86とx64の違いはありますか?これは素晴らしい話題であり、私たちの多くは結果から恩恵を受けることができます。
追加された 著者 Xcalibur37,

Try using the code create application on that machine and see if you get the right readings http://www.microsoft.com/download/en/details.aspx?id=8572

0
追加された
生の値は、 System.Management APIと wmic と上記のツールの両方から同じです。
追加された 著者 wilx,