【问题标题】:WMI, negative CPU usage value and Timestamp_Sys100NS in pastWMI、负 CPU 使用率值和过去的 Timestamp_Sys100NS
【发布时间】:2012-01-06 06:25:11
【问题描述】:

我正在使用 .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;

除了一台(到目前为止)之外,每台机器都运行良好。

问题在于,对于一​​台机器,即 Windows 2003 服务器(启用超线程,如果重要的话),我有时会得到负 CPU 使用率值。换句话说,(double)delta_cpu / delta_time 表达式产生数字> 1。我确实在网上搜索了有关为什么会发生这种情况的提示,但我一无所获。

这是 Windows 2003 服务器特定的吗?还是与超线程相关的问题?还是只是预期的,我应该将 CPU 使用率值或 cpu_delta 值限制在某个范围内?

编辑: 我在这台机器上观察到的第二个奇怪的事情是,Timestamp_Sys100NS 值并不表示 FILETIME 喜欢日期(自 1600 年 1 月 1 日以来的滴答声),而是从启动时间开始的滴答声。

编辑 2: 我现在已经证实这个问题存在于许多 Windows 2003 服务器上。我显然是not the only one with the same problem

编辑 3: 我通过从Win32_OperatingSystem 查询LastBootUpTime 并在Timestamp_Sys100NS 的值过去太远时将其添加到Timestamp_Sys100NS 解决了时间戳问题。这似乎给出了正确的日期和时间。从Win32_OperatingSystem 检索到日期后操作日期的代码如下所示:

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;

...然后是 boot_time 简单地添加到由 WMI 在 Timestamp_Sys100NS 字段中返回的时间戳 (current)...

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

编辑 4: 关于Timestamp_Sys100NS,似乎有3类系统:

  1. 首先是 Vista+ 系统,其中Timestamp_Sys100NS 是UTC 纪元以来的时间。
  2. 其次是一些 Windows 2003 系统,需要将 Timestamp_Sys100NS 添加到 Win32_OperatingSystem.LastBootUpTime 以获得合理的时间。
  3. 第三类是执行上述添加仍会导致日期和时间偏离正确日期和时间的系统。

编辑 5:一些受影响的机器可能是虚拟机,但不是全部。

【问题讨论】:

  • 这意味着CPU正在使用你:)
  • 如何将 LastBootUpTime 添加到 TimeStamp_Sys100NS?你做了什么样的转换?
  • @raz3r:我正在使用System.DateTime(Int64) ctor(需要滴答声)并将其添加到 LastBootUpTime。明天我才能检查确切的细节。

标签: c# .net windows wmi


【解决方案1】:

对我来说,这听起来像是一个标准的“时间同步”问题。

您系统的时钟是...时钟。在您的情况下,您的时钟可能运行得很快(可能在 99% 的实际时间中完成一分钟),因此当您的计算机与外部时钟同步时(例如通过 Windows 时间服务),您的系统时间将向后跳。

或者,用户可以手动调整系统时间(例如:日期和时间控制面板),所以这是您应该设计的东西(如果设置他们的系统时间会使您的应用程序崩溃,您的用户会非常不高兴!)

我解决这个问题的方法是夹紧。总是需要至少 0.0 秒的“实时”时间才能通过,但也需要限制到最多 0.5 秒,因为时间调整可能会向前跳跃,而不仅仅是向后跳跃。

希望对你有帮助。

【讨论】:

  • 不要忘记,至少 0.0 秒意味着您也需要注意被零除
  • 我很确定这是您的问题,所以如果我的解决方案有效,或者如果它最终成为其他问题(假设您再次阅读了一个月前的问题),请回复消息
  • 不良时间信息效果是一致的,不是偶尔发生,而是一直发生。我的代码每 5 秒检查一次。这似乎足够长,不会受到 NTP 守护程序/服务的逐步时间调整的影响。你的回答解释了这个问题,我没有做任何事情。
【解决方案2】:

尝试在该机器上使用代码创建应用程序,看看您是否得到正确的读数 http://www.microsoft.com/download/en/details.aspx?id=8572

【讨论】:

  • System.Management API 和 wmic 以及上述工具的原始值相同。
【解决方案3】:

你具体说的公式是PERF_100NSEC_TIMER_INV http://msdn.microsoft.com/en-us/library/ms803963.aspx

我没有亲自处理过这个问题,因为我从未见过低于零的值。

这就是我一直在做的:

/// <summary>
/// PERF_100NSEC_TIMER_INV algorithm.
/// </summary>
/// <param name="n2"></param>
/// <param name="d2"></param>
/// <param name="n1"></param>
/// <param name="d1"></param>
/// <returns></returns>
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 使用率,它匹配得很好。我认为只要您使用这些值进行计算,您就可以忽略任何小于零的值。

【讨论】:

  • 我不确定您还能做些什么。根据您的发现,我将添加一个检查,以查看 LastBootUpTime > Timestamp_Sys100NS 是否作为标记不准确的直接指标。 WMI 的版本之间存在很多不一致之处。直到 Windows 2003 添加了更好的网络数据和计数器,它们才真正开始变得过于有效。这可能只在 Windows 2003 R1 上吗? x86 和 x64 有区别吗?这是一个很棒的话题,我们中的许多人都可以从结果中受益。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-12
相关资源
最近更新 更多