7

我正在研究电荷平衡系统,因此我需要知道每台机器的电荷。PerformanceCounter 似乎是要走的路,但创建第一个需要 38 到 60 秒。然而,每个后续的新计数器或“NextValue”调用几乎都是即时的。

这是我正在使用的代码:

[TestClass]
public class PerfMon
{
    [TestMethod]
    public void SimpleCreationTest()
    {
        Stopwatch Time = new Stopwatch();
        Time.Start();
        Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds);

        // Create

        PerformanceCounter RAM = new PerformanceCounter("Memory", "Available MBytes");
        Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => RAM created");

        PerformanceCounter CPU = new PerformanceCounter("Processor", "% Processor Time", "_Total");
        Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => CPU created");

        PerformanceCounter GC = new PerformanceCounter(".NET CLR Memory", "% Time in GC", "_Global_");
        Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => GC created");

        // Read

        float Value = RAM.NextValue();
        Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => RAM value is : " + Value);

        Value = CPU.NextValue();
        Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => CPU value is : " + Value);

        Value = GC.NextValue();
        Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => GC value is : " + Value);
    }
}

研究

PerformanceCounter 在连接远程服务器时非常慢

创建一个新的 System.Diagnostics.PerformanceCounter 非常慢

我尝试使用其他构造函数并给出精确的“MachineName”,但它并没有改变任何东西。

为什么调用 PerformanceCounter 很慢?

http://craigandera.blogspot.fr/2005/06/performancecounter-constructor-horribly_21.html

根据这两个线程,问题似乎与性能计数器是共享资源有关。但是我不明白我该如何解决。

在管理员中运行 Visual Studio 将第一次创建从 38 秒“加速”到 26 秒,因此它也不能解决问题。


谢谢你的帮助。

4

2 回答 2

3

我在我的机器上尝试了你的代码,PerformanceCounter的构造函数得到了>2.5 秒。我无法调试 .NET 源代码(我正在运行 VS2013 Express Edition,Windows 7 64b),但我做了一系列实验:

  1. 我调用了 PerformanceCounter的默认构造函数。它立即执行。
  2. 使用 perfmon 我检查了与网络相关的活动。我没有看到什么特别的东西。
  3. 我监控了内存占用。我看到在调用第一个参数化构造函数时,我在代码的内存占用中添加了 ~2.5MB。
  4. 使用 perfmon,我检查了使用的互斥锁、信号量和其他同步对象的计数是否出现峰值。没有什么不寻常的事情发生。
  5. 当不同数量的进程处于活动状态时,我在不同时间测试了代码。我看到有很大的变化。有时我得到 1.4 秒,有时我得到 2.7 有时我得到 5 秒。
  6. 我已经打开了一个 GUI 监控会话并运行了代码,但我没有看到任何收获。

所以我相信不存在设置问题,答案是PerformanceCounter 构造函数执行复杂的工作需要大量时间来执行

所有被监控的事件都是软件事件,可以被操作系统跟踪。所以我想当一个新的 PerformanceCounter 对象被创建时,操作系统必须生成机器的当前状态。这可能意味着获取所有进程的信息,最重要的是,将这些信息存储到可读且可快速访问的结构中。我观察到的是,我拥有的活动进程越多,创建 PerformanceCounter 的速度就越慢。此外,您拥有的核心越多,可能需要收集的数据就越多。

在您发送的最后一个链接中,有一条评论似乎验证了这一理论,但我认为自 2005 年以来自旋锁部分已进行了优化。可能最后的措施是调试构建 PerformanceCounter 的 .NET 源代码。但是我认为这就是它的实现方式。

我要做的是在应用程序的初始化阶段创建我需要的 PerformanceCounter 对象。

于 2015-03-22T18:40:27.160 回答
0

这就是为我解决的问题:

通过确保它作为 64 位进程执行,我的应用程序中的性能计数器设置时间从 2:30 分钟下降到大约 20 秒。有趣的是,我只在 Windows 2012 VM 中遇到了性能问题。在 Windows 10 中没有问题。

于 2018-06-25T12:29:14.830 回答